Pytems

Create & Manage Items in Infinite Craft with an Easy to use Menu!

  1. // ==UserScript==
  2. // @name Pytems
  3. // @namespace https://py9.dev/
  4. // @version 1.1.0
  5. // @description Create & Manage Items in Infinite Craft with an Easy to use Menu!
  6. // @author Py9
  7. // @match https://neal.fun/infinite-craft/
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=neal.fun
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. const version = '1.1.0';
  14. var updateAvailable = false;
  15. let checkVersion = async () => {
  16. let response = await fetch('https://raw.githubusercontent.com/Proyo9/Infinite-Hack/main/version.txt');
  17. let text = await response.text();
  18. let latestVersion = text.trim();
  19. if (compareVersions(version, latestVersion) === -1) {
  20. updateAvailable = true;
  21. document.getElementById('pytems-update').innerText = `Update (v${latestVersion})`;
  22. document.getElementById('pytems-update').style.display = 'flex';
  23. console.log('%cYour Pytems is not up to date, get the latest update from: %chttps://greasyfork.org/en/scripts/487439-pytems', 'color: red; font-weight: bold;', 'color: blue; text-decoration: underline;');
  24. let items = document.querySelectorAll('.item');
  25. /*items.forEach(item => {
  26. if (item.textContent.includes('Thank you for using Pytems')) {
  27. item.innerHTML = `<span data-v-adfd717a="" class="item-emoji">❗</span> Pytems Update Available (v${latestVersion})`;
  28. }
  29. });*/
  30. }
  31. }
  32. function compareVersions(version1, version2) {
  33. const parts1 = version1.split('.');
  34. const parts2 = version2.split('.');
  35. for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
  36. const num1 = parseInt(parts1[i]) || 0;
  37. const num2 = parseInt(parts2[i]) || 0;
  38.  
  39. if (num1 < num2) {
  40. return -1;
  41. } else if (num1 > num2) {
  42. return 1;
  43. }
  44. }
  45. return 0;
  46. }
  47. checkVersion();
  48. let script = document.createElement('script');
  49. script.src = 'https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js';
  50. script.type = 'module';
  51. document.head.appendChild(script);
  52. let ht = localStorage.getItem('pytems:hidethanks');
  53. let items = localStorage.getItem('infinite-craft-data')
  54. if (items === null) {
  55. items = {"elements":[{"text":"Water","emoji":"💧","discovered":false},{"text":"Fire","emoji":"🔥","discovered":false},{"text":"Wind","emoji":"🌬️","discovered":false},{"text":"Earth","emoji":"🌍","discovered":false}]}
  56. } else {
  57. items = JSON.parse(items)
  58. }
  59. if (ht && !updateAvailable) {
  60. items.elements = items.elements.filter(e => e.text !== 'Thank you for using Pytems');
  61. localStorage.setItem('infinite-craft-data', JSON.stringify(items));
  62. } else {
  63. localStorage.setItem('infinite-craft-data', JSON.stringify(items))
  64. let thanks = {"text":"Thank you for using Pytems","emoji":"🍉","discovered":false}
  65. if (!items.elements.some(e => e.text === thanks.text)) {
  66. items.elements.unshift(thanks)
  67. }
  68. localStorage.setItem('infinite-craft-data', JSON.stringify(items))
  69. }
  70.  
  71. let cheatsDisabled = localStorage.getItem('pytems:cheats');
  72. let buttonContainer = document.createElement('div');
  73. buttonContainer.style.display = 'flex';
  74. buttonContainer.style.justifyContent = 'center';
  75. document.body.appendChild(buttonContainer);
  76. let createButton = document.createElement('button');
  77. createButton.textContent = 'Create Item';
  78. createButton.style.zIndex = 1000000;
  79. createButton.style.padding = '10px 20px';
  80. createButton.style.backgroundColor = '#4CAF50';
  81. createButton.style.color = 'white';
  82. createButton.style.border = 'none';
  83. createButton.style.borderRadius = '5px';
  84. createButton.style.cursor = 'pointer';
  85. createButton.style.marginTop = '10px';
  86. if (cheatsDisabled) { createButton.style.display = 'none'; }
  87. buttonContainer.appendChild(createButton);
  88. createButton.addEventListener('click', function() {
  89. document.querySelectorAll('.sidebar-input').forEach(input => input.disabled = true);
  90. createItemMenu.style.display = 'flex';
  91. });
  92. let deleteButton = document.createElement('button');
  93. deleteButton.textContent = 'Delete Item';
  94. deleteButton.style.zIndex = 1000000;
  95. deleteButton.style.padding = '10px 20px';
  96. deleteButton.style.backgroundColor = '#f44336';
  97. deleteButton.style.color = 'white';
  98. deleteButton.style.border = 'none';
  99. deleteButton.style.borderRadius = '5px';
  100. deleteButton.style.cursor = 'pointer';
  101. deleteButton.style.marginLeft = '10px';
  102. deleteButton.style.marginTop = '10px';
  103. if (cheatsDisabled) { deleteButton.style.display = 'none'; }
  104. buttonContainer.appendChild(deleteButton);
  105. deleteButton.addEventListener('click', function() {
  106. document.querySelectorAll('.sidebar-input').forEach(input => input.disabled = true);
  107. deleteItemMenu.style.display = 'flex';
  108. });
  109.  
  110. let magicCreateButton = document.createElement('button');
  111. magicCreateButton.textContent = 'Magic Create';
  112. magicCreateButton.style.zIndex = 1000000;
  113. magicCreateButton.style.padding = '10px 20px';
  114. magicCreateButton.style.backgroundColor = '#6779d0';
  115. magicCreateButton.style.color = 'white';
  116. magicCreateButton.style.border = 'none';
  117. magicCreateButton.style.borderRadius = '5px';
  118. magicCreateButton.style.cursor = 'pointer';
  119. magicCreateButton.style.marginLeft = '10px';
  120. magicCreateButton.style.marginTop = '10px';
  121. buttonContainer.appendChild(magicCreateButton);
  122. if (cheatsDisabled) { magicCreateButton.style.display = 'none'; }
  123. magicCreateButton.addEventListener('click', function() {
  124. document.querySelectorAll('.sidebar-input').forEach(input => input.disabled = true);
  125. magicCreateMenu.style.display = 'flex';
  126. });
  127.  
  128. let magicCreateMenu = document.createElement('div');
  129. magicCreateMenu.style.position = 'fixed';
  130. magicCreateMenu.style.top = '15%';
  131. magicCreateMenu.style.left = '50%';
  132. magicCreateMenu.style.transform = 'translateX(-50%)';
  133. magicCreateMenu.style.zIndex = 1000000;
  134. magicCreateMenu.style.padding = '20px';
  135. magicCreateMenu.style.backgroundColor = 'white';
  136. magicCreateMenu.style.borderRadius = '5px';
  137. magicCreateMenu.style.display = 'none';
  138. magicCreateMenu.style.flexDirection = 'column';
  139. magicCreateMenu.style.alignItems = 'center';
  140. magicCreateMenu.style.justifyContent = 'center';
  141. magicCreateMenu.style.border = '1px solid #ddd';
  142. magicCreateMenu.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
  143. document.body.appendChild(magicCreateMenu);
  144.  
  145. let firstElementInput = document.createElement('input');
  146. firstElementInput.style.padding = '10px';
  147. firstElementInput.style.margin = '5px';
  148. firstElementInput.style.width = '100%';
  149. firstElementInput.style.border = '1px solid #ddd';
  150. firstElementInput.style.borderRadius = '5px';
  151. firstElementInput.style.fontSize = '16px';
  152. firstElementInput.style.outline = 'none';
  153. firstElementInput.placeholder = "Element One";
  154. magicCreateMenu.appendChild(firstElementInput);
  155.  
  156. let secondElementInput = document.createElement('input');
  157. secondElementInput.style.padding = '10px';
  158. secondElementInput.style.margin = '5px';
  159. secondElementInput.style.width = '100%';
  160. secondElementInput.style.border = '1px solid #ddd';
  161. secondElementInput.style.borderRadius = '5px';
  162. secondElementInput.style.fontSize = '16px';
  163. secondElementInput.style.outline = 'none';
  164. secondElementInput.placeholder = "Element Two";
  165. magicCreateMenu.appendChild(secondElementInput);
  166.  
  167. let magicCreateButton2 = document.createElement('button');
  168. magicCreateButton2.textContent = 'Create';
  169. magicCreateButton2.style.zIndex = 1000000;
  170. magicCreateButton2.style.padding = '10px 20px';
  171. magicCreateButton2.style.backgroundColor = '#6779d0';
  172. magicCreateButton2.style.color = 'white';
  173. magicCreateButton2.style.border = 'none';
  174. magicCreateButton2.style.borderRadius = '5px';
  175. magicCreateButton2.style.cursor = 'pointer';
  176. magicCreateButton2.style.marginTop = '10px';
  177. magicCreateMenu.appendChild(magicCreateButton2);
  178.  
  179. magicCreateButton2.addEventListener('click', function() {
  180. const firstElement = firstElementInput.value;
  181. const secondElement = secondElementInput.value;
  182. var text = '';
  183. fetch(`https://neal.fun/api/infinite-craft/pair?first=${firstElement}&second=${secondElement}`)
  184. .then(response => {
  185. if (!response.ok) {
  186. throw new Error('Network response was not ok');
  187. }
  188. // Return the ReadableStream directly
  189. return response.body;
  190. })
  191. .then(body => {
  192. const reader = body.getReader();
  193.  
  194. const readStream = () => {
  195. return reader.read().then(({ done, value }) => {
  196. if (done) {
  197. responseJSON = JSON.parse(text);
  198. let newItem = {"text":responseJSON.result,"emoji":responseJSON.emoji,"discovered":responseJSON.isNew};
  199. items = localStorage.getItem('infinite-craft-data')
  200. items = JSON.parse(items)
  201. items.elements.push(newItem);
  202. localStorage.setItem('infinite-craft-data', JSON.stringify(items))
  203. location.reload();
  204. return;
  205. }
  206. text += new TextDecoder().decode(value);
  207. return readStream();
  208. });
  209. };
  210.  
  211. return readStream();
  212. })
  213. .catch(error => {
  214. console.error('There was a problem with the fetch operation:', error);
  215. });
  216.  
  217. magicCreateMenu.remove();
  218. });
  219.  
  220. let createItemMenu = document.createElement('div');
  221. createItemMenu.style.position = 'fixed';
  222. createItemMenu.style.top = '15%';
  223. createItemMenu.style.left = '50%';
  224. createItemMenu.style.transform = 'translateX(-50%)';
  225. createItemMenu.style.zIndex = 1000000;
  226. createItemMenu.style.padding = '20px';
  227. createItemMenu.style.backgroundColor = 'white';
  228. createItemMenu.style.borderRadius = '5px';
  229. createItemMenu.style.display = 'none';
  230. createItemMenu.style.flexDirection = 'column';
  231. createItemMenu.style.alignItems = 'center';
  232. createItemMenu.style.justifyContent = 'center';
  233. createItemMenu.style.border = '1px solid #ddd';
  234. createItemMenu.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
  235. document.body.appendChild(createItemMenu);
  236.  
  237. let createItemInput = document.createElement('input');
  238. createItemInput.style.padding = '10px';
  239. createItemInput.style.margin = '5px';
  240. createItemInput.style.width = '100%';
  241. createItemInput.style.border = '1px solid #ddd';
  242. createItemInput.style.borderRadius = '5px';
  243. createItemInput.style.fontSize = '16px';
  244. createItemInput.style.outline = 'none';
  245. createItemInput.placeholder = 'Enter the name of the item';
  246. createItemInput.value = 'New Item';
  247. createItemMenu.appendChild(createItemInput);
  248. let createItemEmoji = document.createElement('input');
  249. createItemEmoji.style.padding = '10px';
  250. createItemEmoji.style.margin = '5px';
  251. createItemEmoji.style.width = '100%';
  252. createItemEmoji.style.border = '1px solid #ddd';
  253. createItemEmoji.style.borderRadius = '5px';
  254. createItemEmoji.style.fontSize = '16px';
  255. createItemEmoji.style.outline = 'none';
  256. createItemEmoji.placeholder = 'Enter the emoji for the item';
  257. createItemEmoji.value = '📋';
  258. createItemMenu.appendChild(createItemEmoji);
  259. let pickerButton = document.createElement('button');
  260. pickerButton.textContent = 'Pick Emoji';
  261. pickerButton.style.padding = '10px 20px';
  262. pickerButton.style.backgroundColor = '#2196F3';
  263. pickerButton.style.color = 'white';
  264. pickerButton.style.border = 'none';
  265. pickerButton.style.borderRadius = '5px';
  266. pickerButton.style.cursor = 'pointer';
  267. pickerButton.style.marginBottom = '10px';
  268. createItemMenu.appendChild(pickerButton);
  269. pickerButton.addEventListener('click', function() {
  270. pickerButton.style.display = 'none';
  271. emojiPicker.style.display = 'flex';
  272. }
  273. );
  274. let emojiPicker = document.createElement('emoji-picker');
  275. emojiPicker.style.marginTop = '10px';
  276. emojiPicker.style.marginBottom = '10px';
  277. emojiPicker.style.display = 'none';
  278. emojiPicker.addEventListener('emoji-click', (event) => {
  279. createItemEmoji.value = event.detail.emoji.unicode;
  280. emojiPicker.style.display = 'none';
  281. pickerButton.style.display = 'flex';
  282. });
  283. createItemMenu.appendChild(emojiPicker);
  284. let createItemDiscoveredLabel = document.createElement('label');
  285. createItemDiscoveredLabel.textContent = 'Discovered';
  286. createItemDiscoveredLabel.style.fontSize = '16px';
  287. createItemDiscoveredLabel.style.outline = 'none';
  288. createItemMenu.appendChild(createItemDiscoveredLabel);
  289. let createItemDiscovered = document.createElement('input');
  290. createItemDiscovered.type = 'checkbox';
  291. createItemDiscovered.style.border = '1px solid #ddd';
  292. createItemDiscovered.style.borderRadius = '5px';
  293. createItemDiscovered.style.fontSize = '16px';
  294. createItemDiscovered.style.outline = 'none';
  295. createItemDiscovered.style.marginBottom = '5px';
  296. createItemMenu.appendChild(createItemDiscovered);
  297. let createItemSubmit = document.createElement('button');
  298. createItemSubmit.textContent = 'Create Item';
  299. createItemSubmit.style.padding = '10px 20px';
  300. createItemSubmit.style.backgroundColor = '#4CAF50';
  301. createItemSubmit.style.color = 'white';
  302. createItemSubmit.style.border = 'none';
  303. createItemSubmit.style.borderRadius = '5px';
  304. createItemSubmit.style.cursor = 'pointer';
  305. createItemMenu.appendChild(createItemSubmit);
  306. createItemSubmit.addEventListener('click', function() {
  307. let newItem = {"text":createItemInput.value,"emoji":createItemEmoji.value,"discovered":createItemDiscovered.checked};
  308. items = localStorage.getItem('infinite-craft-data')
  309. items = JSON.parse(items)
  310. items.elements.push(newItem);
  311. localStorage.setItem('infinite-craft-data', JSON.stringify(items))
  312. location.reload();
  313. });
  314. let deleteItemMenu = document.createElement('div');
  315. deleteItemMenu.style.position = 'fixed';
  316. deleteItemMenu.style.top = '15%';
  317. deleteItemMenu.style.left = '50%';
  318. deleteItemMenu.style.transform = 'translateX(-50%)';
  319. deleteItemMenu.style.zIndex = 1000000;
  320. deleteItemMenu.style.padding = '20px';
  321. deleteItemMenu.style.backgroundColor = 'white';
  322. deleteItemMenu.style.borderRadius = '5px';
  323. deleteItemMenu.style.display = 'none';
  324. deleteItemMenu.style.flexDirection = 'column';
  325. deleteItemMenu.style.alignItems = 'center';
  326. deleteItemMenu.style.justifyContent = 'center';
  327. deleteItemMenu.style.border = '1px solid #ddd';
  328. deleteItemMenu.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
  329. document.body.appendChild(deleteItemMenu);
  330.  
  331. let deleteItemInput = document.createElement('input');
  332. deleteItemInput.style.padding = '10px';
  333. deleteItemInput.style.margin = '5px';
  334. deleteItemInput.style.width = '100%';
  335. deleteItemInput.style.border = '1px solid #ddd';
  336. deleteItemInput.style.borderRadius = '5px';
  337. deleteItemInput.style.fontSize = '16px';
  338. deleteItemInput.style.outline = 'none';
  339. deleteItemInput.placeholder = 'Enter the name of the item';
  340. deleteItemMenu.appendChild(deleteItemInput);
  341. let deleteItemSubmit = document.createElement('button');
  342. deleteItemSubmit.textContent = 'Delete Item';
  343. deleteItemSubmit.style.padding = '10px 20px';
  344. deleteItemSubmit.style.backgroundColor = '#f44336';
  345. deleteItemSubmit.style.color = 'white';
  346. deleteItemSubmit.style.border = 'none';
  347. deleteItemSubmit.style.borderRadius = '5px';
  348. deleteItemSubmit.style.cursor = 'pointer';
  349. deleteItemMenu.appendChild(deleteItemSubmit);
  350. deleteItemSubmit.addEventListener('click', function() {
  351. items = localStorage.getItem('infinite-craft-data')
  352. items = JSON.parse(items)
  353. items.elements = items.elements.filter(e => e.text !== deleteItemInput.value)
  354. localStorage.setItem('infinite-craft-data', JSON.stringify(items))
  355. location.reload();
  356. });
  357.  
  358. let updateButton = document.createElement('button');
  359. updateButton.textContent = 'Update';
  360. updateButton.style.zIndex = 1000000;
  361. updateButton.style.padding = '10px 20px';
  362. updateButton.style.backgroundColor = '#2196F3';
  363. updateButton.style.color = 'white';
  364. updateButton.style.border = 'none';
  365. updateButton.style.borderRadius = '5px';
  366. updateButton.style.cursor = 'pointer';
  367. updateButton.style.marginLeft = '10px';
  368. updateButton.style.marginTop = '10px';
  369. updateButton.style.display = 'none';
  370. updateButton.id = 'pytems-update';
  371. buttonContainer.appendChild(updateButton);
  372. updateButton.addEventListener('click', function() {
  373. window.open('https://greasyfork.org/en/scripts/487439-pytems', '_blank');
  374. });
  375.  
  376. let settingsMenu = document.createElement('div');
  377. settingsMenu.style.position = 'fixed';
  378. settingsMenu.style.top = '15%';
  379. settingsMenu.style.right = '50%';
  380. settingsMenu.style.transform = 'translateX(50%)';
  381. settingsMenu.style.zIndex = 1000000;
  382. settingsMenu.style.padding = '20px';
  383. settingsMenu.style.backgroundColor = 'white';
  384. settingsMenu.style.borderRadius = '5px';
  385. settingsMenu.style.display = 'none';
  386. settingsMenu.style.flexDirection = 'column';
  387. settingsMenu.style.alignItems = 'center';
  388. settingsMenu.style.justifyContent = 'center';
  389. settingsMenu.style.border = '1px solid #ddd';
  390. settingsMenu.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
  391. document.body.appendChild(settingsMenu);
  392.  
  393. settingsMenu.innerHTML = `
  394. <style>
  395. #pytems-github {
  396. margin-top: 10px;
  397. color: #2196F3;
  398. text-decoration: none;
  399. }
  400. #pytems-github:hover {
  401. text-decoration: underline;
  402. }
  403. #pytems-settings-close {
  404. margin-top: 10px;
  405. padding: 10px 20px;
  406. background-color: #f44336;
  407. color: white;
  408. border: none;
  409. border-radius: 5px;
  410. cursor: pointer;
  411. }
  412. #pytems-settings-close:hover {
  413. background-color: #ff6666;
  414. }
  415. .checkbox-info {
  416. margin-top: 10px;
  417. }
  418. .pytems-label {
  419. margin-left: 10px;
  420. }
  421. </style>
  422. <h1>Pytems Settings</h1>
  423. <span class="checkbox-info"><input type="checkbox" id="pytems-setting-hidethanks"></input><label for="pytems-setting-hidethanks" class="pytems-label">Hide Thanks Item</label></span>
  424. <span class="checkbox-info"><input type="checkbox" id="pytems-setting-cheats"></input><label for="pytems-setting-cheats" class="pytems-label">Disable Cheats</label></span>
  425. <a href="https://github.com/Proyo9/Infinite-Hack/" target="_blank" id="pytems-github">GitHub</a>
  426. <button id="pytems-settings-close">Close</button>
  427. `;
  428.  
  429. let settingsClose = document.getElementById('pytems-settings-close');
  430. settingsClose.addEventListener('click', function() {
  431. // save settings
  432. let hideThanks = document.getElementById('pytems-setting-hidethanks').checked;
  433. hideThanks ? localStorage.setItem('pytems:hidethanks', hideThanks) : localStorage.removeItem('pytems:hidethanks');
  434. let cheats = document.getElementById('pytems-setting-cheats').checked;
  435. cheats ? localStorage.setItem('pytems:cheats', cheats) : localStorage.removeItem('pytems:cheats');
  436.  
  437. window.location.reload();
  438. });
  439.  
  440. let hideThanks = localStorage.getItem('pytems:hidethanks');
  441. if (hideThanks) {
  442. document.getElementById('pytems-setting-hidethanks').checked = true;
  443. }
  444. let cheats = localStorage.getItem('pytems:cheats');
  445. if (cheats) {
  446. document.getElementById('pytems-setting-cheats').checked = true;
  447. }
  448.  
  449. let saveManagerMenu = document.createElement('div');
  450. saveManagerMenu.style.position = 'fixed';
  451. saveManagerMenu.style.top = '15%';
  452. saveManagerMenu.style.right = '50%';
  453. saveManagerMenu.style.transform = 'translateX(50%)';
  454. saveManagerMenu.style.zIndex = 1000000;
  455. saveManagerMenu.style.padding = '20px';
  456. saveManagerMenu.style.backgroundColor = 'white';
  457. saveManagerMenu.style.borderRadius = '5px';
  458. saveManagerMenu.style.display = 'none';
  459. saveManagerMenu.style.flexDirection = 'column';
  460. saveManagerMenu.style.alignItems = 'center';
  461. saveManagerMenu.style.justifyContent = 'center';
  462. saveManagerMenu.style.border = '1px solid #ddd';
  463. saveManagerMenu.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
  464. document.body.appendChild(saveManagerMenu);
  465.  
  466. const styles = `
  467. <style>
  468. #pytems-save-close {
  469. margin-top: 10px;
  470. padding: 10px 20px;
  471. background-color: #f44336;
  472. color: white;
  473. border: none;
  474. border-radius: 5px;
  475. cursor: pointer;
  476. }
  477. #pytems-save-close:hover {
  478. background-color: #ff6666;
  479. }
  480. .pytems-label {
  481. margin-left: 10px;
  482. }
  483. .select-sm,
  484. .input-sm {
  485. padding: 10px;
  486. margin-bottom: 10px;
  487. width: 100%;
  488. border: 1px solid #ddd;
  489. border-radius: 5px;
  490. font-size: 16px;
  491. outline: none;
  492. }
  493. .button-sm {
  494. padding: 10px 20px;
  495. background-color: #4CAF50;
  496. color: white;
  497. border: none;
  498. border-radius: 5px;
  499. cursor: pointer;
  500. }
  501. </style>
  502. `;
  503.  
  504. const renderSaveManagerMenu = (title, content) => {
  505. saveManagerMenu.innerHTML = `
  506. ${styles}
  507. <h1>${title}</h1>
  508. ${content}
  509. `;
  510. };
  511.  
  512. const reloadPage = () => {
  513. window.location.reload();
  514. };
  515.  
  516. const saveData = (saveName) => {
  517. const saveData = localStorage.getItem('infinite-craft-data');
  518. localStorage.setItem(`pytems-save:${saveName}`, saveData);
  519. saveManagerMenu.style.display = 'none';
  520. reloadPage();
  521. };
  522.  
  523. const loadData = (saveName) => {
  524. if (saveName === '') return;
  525. const saveData = localStorage.getItem(`pytems-save:${saveName}`);
  526. localStorage.setItem('infinite-craft-data', saveData);
  527. reloadPage();
  528. };
  529.  
  530. const deleteData = (saveName) => {
  531. localStorage.removeItem(`pytems-save:${saveName}`);
  532. reloadPage();
  533. };
  534.  
  535. renderSaveManagerMenu('Save Manager', `
  536. <p>This feature is in beta, there are a lot of UI bugs</p>
  537. <select id="pytems-sm-type" style="margin-bottom: 10px;" class="select-sm">
  538. <option value="save">Save</option>
  539. <option value="load">Load</option>
  540. <option value="delete">Delete</option>
  541. </select>
  542. <span class="sm-buttons">
  543. <button id="pytems-sm-Cancel" class="button-sm" style="background-color: #f44336;">Cancel</button>
  544. <button id="pytems-sm-next" class="button-sm">Next</button>
  545. </span>
  546. `);
  547.  
  548. const smType = document.getElementById('pytems-sm-type');
  549. const smNext = document.getElementById('pytems-sm-next');
  550. const smCancel = document.getElementById('pytems-sm-Cancel');
  551.  
  552. smCancel.addEventListener('click', reloadPage);
  553.  
  554. smNext.addEventListener('click', () => {
  555. const type = smType.value;
  556. if (type === 'save') {
  557. renderSaveManagerMenu('Save Manager', `
  558. <input type="text" id="pytems-sm-save-name" placeholder="Save Name" style="margin-bottom: 10px;" class="input-sm">
  559. <span class="sm-buttons">
  560. <button id="pytems-sm-Cancel" class="button-sm" style="background-color: #f44336;">Cancel</button>
  561. <button id="pytems-sm-save" class="button-sm">Save</button>
  562. </span>
  563. `);
  564. const smSave = document.getElementById('pytems-sm-save');
  565. smSave.addEventListener('click', () => {
  566. const saveName = document.getElementById('pytems-sm-save-name').value;
  567. saveData(saveName);
  568. });
  569. } else if (type === 'load') {
  570. const saveNames = Object.keys(localStorage).filter(key => key.startsWith('pytems-save:')).map(key => key.replace('pytems-save:', ''));
  571. renderSaveManagerMenu('Save Manager', `
  572. <select id="pytems-sm-save-name" style="margin-bottom: 10px;" class="select-sm">
  573. ${saveNames.map(name => `<option value="${name}">${name}</option>`).join('')}
  574. </select>
  575. <span class="sm-buttons">
  576. <button id="pytems-sm-Cancel" class="button-sm" style="background-color: #f44336;">Cancel</button>
  577. <button id="pytems-sm-load" class="button-sm">Load</button>
  578. </span>
  579. `);
  580. const smLoad = document.getElementById('pytems-sm-load');
  581. smLoad.addEventListener('click', () => {
  582. const saveName = document.getElementById('pytems-sm-save-name').value;
  583. loadData(saveName);
  584. });
  585. } else if (type === 'delete') {
  586. const saveNames = Object.keys(localStorage).filter(key => key.startsWith('pytems-save:')).map(key => key.replace('pytems-save:', ''));
  587. renderSaveManagerMenu('Save Manager', `
  588. <select id="pytems-sm-save-name" style="margin-bottom: 10px;" class="select-sm">
  589. ${saveNames.map(name => `<option value="${name}">${name}</option>`).join('')}
  590. </select>
  591. <span class="sm-buttons">
  592. <button id="pytems-sm-Cancel" class="button-sm" style="background-color: #f44336;">Cancel</button>
  593. <button id="pytems-sm-delete" class="button-sm">Delete</button>
  594. </span>
  595. `);
  596. const smDelete = document.getElementById('pytems-sm-delete');
  597. smDelete.addEventListener('click', () => {
  598. const saveName = document.getElementById('pytems-sm-save-name').value;
  599. deleteData(saveName);
  600. });
  601. }
  602. smCancel.addEventListener('click', reloadPage);
  603. });
  604.  
  605. let darkmodesetting = localStorage.getItem('pytems:darkmode');
  606. if (darkmodesetting) {
  607. setTimeout(() => {
  608. // darkmode
  609. let customstyle = document.createElement('style');
  610. customstyle.id = 'pytems-style';
  611. customstyle.innerHTML = `
  612. body {
  613. color: white !important;
  614. }
  615. .items {
  616. background-color: #1e1e1e !important;
  617. color: white !important;
  618. }
  619. .item {
  620. background-color: #2e2e2e !important;
  621. color: white !important;
  622. }
  623. .item:hover {
  624. background: #3e3e3e !important;
  625. }
  626. .container {
  627. background-color: #1e1e1e !important;
  628. }
  629. .reset {
  630. color: white !important;
  631. }
  632. .sidebar-sorting-item {
  633. background-color: #2e2e2e !important;
  634. color: white !important;
  635. }
  636. .sidebar-input {
  637. background-color: #2e2e2e !important;
  638. color: white !important;
  639. }
  640. .item-selected {
  641. background: #3e3e3e !important;
  642. }
  643. .instance {
  644. background: #2e2e2e !important;
  645. }
  646. ::-webkit-scrollbar {
  647. width: 10px;
  648. }
  649. ::-webkit-scrollbar-track {
  650. background: #2e2e2e;
  651. }
  652. ::-webkit-scrollbar-thumb {
  653. background: #3e3e3e;
  654. }
  655. ::-webkit-scrollbar-thumb:hover {
  656. background: #4e4e4e;
  657. }
  658. input {
  659. color: white !important;
  660. background-color: #2e2e2e !important;
  661. }
  662. img {
  663. filter: invert(1) !important;
  664. }
  665. `
  666. let emojiPicker = document.querySelector('emoji-picker');
  667. emojiPicker.classList.add('dark');
  668. createButton.style.backgroundColor = 'transparent';
  669. createButton.style.border = 'solid 2px #4CAF50';
  670. deleteButton.style.backgroundColor = 'transparent';
  671. deleteButton.style.border = 'solid 2px #f44336';
  672. magicCreateButton.style.backgroundColor = 'transparent';
  673. magicCreateButton.style.border = 'solid 2px #6779d0';
  674. document.head.appendChild(customstyle);
  675. let checkImagesInterval = setInterval(() => {
  676. let images = document.querySelectorAll('img');
  677. if (images.length === 9) {
  678. clearInterval(checkImagesInterval);
  679. images.forEach(image => {
  680. image.style.filter = 'invert(1)';
  681. });
  682. }
  683. }, 100);
  684. let checkCanvasInterval = setInterval(() => {
  685. let canvas = document.querySelector('.particles');
  686. if (canvas) {
  687. clearInterval(checkCanvasInterval);
  688. canvas.style.filter = 'invert(1)';
  689. }
  690. }, 100);
  691. createItemMenu.style.backgroundColor = '#2e2e2e';
  692. deleteItemMenu.style.backgroundColor = '#2e2e2e';
  693. magicCreateMenu.style.backgroundColor = '#2e2e2e';
  694. settingsMenu.style.backgroundColor = '#2e2e2e';
  695. saveManagerMenu.style.backgroundColor = '#2e2e2e';
  696. }, 10);
  697. }
  698.  
  699. setTimeout(() => {
  700. let darkmodeToggle = `
  701. <a data-v-0d6976f8="" target="_blank" class="darkmodetoggle" id="darkmodetoggle" style="margin-top: 3.5px;">
  702. <img data-v-0d6976f8="" src="https://static-00.iconduck.com/assets.00/moon-icon-1868x2048-ifpp8fum.png" class="coffee" style="width: 18px; height: 18px;">
  703. </a>
  704. `
  705. let settingsToggle = `
  706. <a data-v-0d6976f8="" target="_blank" class="settingstoggle" id="settingstoggle" style="margin-top: 4px;">
  707. <img data-v-0d6976f8="" src="https://static-00.iconduck.com/assets.00/gear-icon-2048x2048-5lk2g86a.png" class="coffee" style="width: 18px; height: 18px;">
  708. </a>
  709. `
  710. let saveManager = `
  711. <a data-v-0d6976f8="" target="_blank" class="saveManager" id="saveManager" style="margin-top: 4px;">
  712. <img data-v-0d6976f8="" src="https://static-00.iconduck.com/assets.00/save-icon-512x512-552twxqx.png" class="coffee" style="width: 18px; height: 18px;">
  713. </a>
  714. `
  715. let sideControls = document.querySelector('.side-controls');
  716. sideControls.innerHTML = darkmodeToggle + settingsToggle + saveManager + sideControls.innerHTML;
  717. let darkmodeButton = document.getElementById('darkmodetoggle');
  718. darkmodeButton.addEventListener('click', function() {
  719. if (localStorage.getItem('pytems:darkmode')) {
  720. localStorage.removeItem('pytems:darkmode');
  721. location.reload();
  722. } else {
  723. localStorage.setItem('pytems:darkmode', 'true');
  724. location.reload();
  725. }
  726. });
  727. let settingsButton = document.getElementById('settingstoggle');
  728. settingsButton.addEventListener('click', function() {
  729. settingsMenu.style.display = 'flex';
  730. });
  731. document.querySelector('.clear').addEventListener('click', function() {
  732. window.location.reload()
  733. /*document.querySelectorAll('.instance').forEach(instance => {
  734. instance.remove();
  735. });*/
  736. });
  737. let saveManagerButton = document.getElementById('saveManager');
  738. saveManagerButton.addEventListener('click', function() {
  739. saveManagerMenu.style.display = 'flex';
  740. document.querySelectorAll('.sidebar-input').forEach(input => input.disabled = true);
  741. });
  742. }, 500);
  743. })();