PixAI UI Helpers

Helpers for PixAI: Toggle between 4x1 and 2x2 layouts for the image grid, toggle the visibility of the right sidebar, and enable "Ctrl+Enter" for generating images. Remembers layout and Ctrl+Enter settings across refreshes.

当前为 2024-08-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name PixAI UI Helpers
  3. // @namespace http://yourname.tampermonkey.net/
  4. // @version 1.4
  5. // @description Helpers for PixAI: Toggle between 4x1 and 2x2 layouts for the image grid, toggle the visibility of the right sidebar, and enable "Ctrl+Enter" for generating images. Remembers layout and Ctrl+Enter settings across refreshes.
  6. // @author Yada
  7. // @match https://pixai.art/*
  8. // @icon https://pixai.art/favicon.ico
  9. // @grant none
  10. // @license MIT
  11. // @supportURL http://yoursupporturl.com/script.js
  12. // ==/UserScript==
  13. (function() {
  14. 'use strict';
  15.  
  16. let is2x2Layout = localStorage.getItem('pixai-layout') === '2x2';
  17. let isCtrlEnterEnabled = localStorage.getItem('pixai-ctrl-enter') === 'enabled';
  18. let isRightBarCollapsed = false;
  19. let buttonsAdded = false;
  20. let layoutInterval;
  21.  
  22. // Function to get the target element for grid layout
  23. function getGridTargetElement() {
  24. return document.querySelector('#workbench-layout main > div > div:nth-child(2) > div > div:nth-child(1)');
  25. }
  26.  
  27. // Function to set the layout to 4x1
  28. function setLayout4x1() {
  29. const imageContainer = getGridTargetElement();
  30. if (imageContainer) {
  31. imageContainer.style.setProperty('--grid-cols', '4');
  32. imageContainer.style.setProperty('--grid-rows', '1');
  33. is2x2Layout = false;
  34. localStorage.setItem('pixai-layout', '4x1');
  35. }
  36. }
  37.  
  38. // Function to set the layout to 2x2
  39. function setLayout2x2() {
  40. const imageContainer = getGridTargetElement();
  41. if (imageContainer) {
  42. imageContainer.style.setProperty('--grid-cols', '2');
  43. imageContainer.style.setProperty('--grid-rows', '2');
  44. is2x2Layout = true;
  45. localStorage.setItem('pixai-layout', '2x2');
  46. }
  47. }
  48.  
  49. // Function to reapply the current layout
  50. function reapplyLayout() {
  51. if (is2x2Layout) {
  52. setLayout2x2();
  53. } else {
  54. setLayout4x1();
  55. }
  56. }
  57.  
  58. // Function to toggle between layouts
  59. function toggleLayout() {
  60. is2x2Layout = !is2x2Layout;
  61. reapplyLayout();
  62. }
  63.  
  64. // Function to set right bar width to zero
  65. function setRightBarWidthToZero() {
  66. const workbenchLayout = document.querySelector('#workbench-layout');
  67. if (workbenchLayout) {
  68. workbenchLayout.style.gridTemplateColumns = 'min-content 1fr 0px';
  69. isRightBarCollapsed = true;
  70. }
  71. }
  72.  
  73. // Function to restore the original width of the right bar
  74. function restoreRightBarWidth() {
  75. const workbenchLayout = document.querySelector('#workbench-layout');
  76. if (workbenchLayout) {
  77. workbenchLayout.style.gridTemplateColumns = 'min-content 1fr 380px';
  78. isRightBarCollapsed = false;
  79. }
  80. }
  81.  
  82. // Function to toggle the right bar's visibility
  83. function toggleRightBar() {
  84. if (isRightBarCollapsed) {
  85. restoreRightBarWidth();
  86. } else {
  87. setRightBarWidthToZero();
  88. }
  89. }
  90.  
  91. // Function to handle Ctrl+Enter key press for generating images
  92. function handleCtrlEnter(event) {
  93. if (event.ctrlKey && event.key === 'Enter') {
  94. const generateButton = document.querySelector('[data-tutorial-target="generate-button"]');
  95. if (generateButton) {
  96. generateButton.click();
  97. }
  98. }
  99. }
  100.  
  101. // Function to enable Ctrl+Enter for generating images
  102. function enableCtrlEnter() {
  103. if (!isCtrlEnterEnabled) {
  104. document.addEventListener('keydown', handleCtrlEnter);
  105. isCtrlEnterEnabled = true;
  106. localStorage.setItem('pixai-ctrl-enter', 'enabled');
  107. }
  108. }
  109.  
  110. // Function to disable Ctrl+Enter for generating images
  111. function disableCtrlEnter() {
  112. if (isCtrlEnterEnabled) {
  113. document.removeEventListener('keydown', handleCtrlEnter);
  114. isCtrlEnterEnabled = false;
  115. localStorage.setItem('pixai-ctrl-enter', 'disabled');
  116. }
  117. }
  118.  
  119. // Function to toggle Ctrl+Enter feature
  120. function toggleCtrlEnter() {
  121. if (isCtrlEnterEnabled) {
  122. disableCtrlEnter();
  123. } else {
  124. enableCtrlEnter();
  125. }
  126. }
  127.  
  128. // Function to add the buttons
  129. function addButtons() {
  130. if (buttonsAdded) return;
  131.  
  132. // Create button container
  133. const buttonContainer = document.createElement('div');
  134. buttonContainer.id = 'pixai-ui-helpers-buttons';
  135. buttonContainer.style.position = 'fixed';
  136. buttonContainer.style.top = '10px';
  137. buttonContainer.style.right = '10px';
  138. buttonContainer.style.zIndex = '1000';
  139. buttonContainer.style.display = 'flex';
  140. buttonContainer.style.flexDirection = 'row';
  141. buttonContainer.style.gap = '5px';
  142.  
  143. // Button styles
  144. const buttonStyle = {
  145. display: 'flex',
  146. justifyContent: 'center',
  147. alignItems: 'center',
  148. backgroundColor: 'transparent',
  149. color: 'white',
  150. fontFamily: 'Inter, sans-serif',
  151. fontSize: '0.75rem',
  152. fontWeight: '500',
  153. textShadow: '0 1px 2px rgba(0, 0, 0, 0.5)',
  154. padding: '0.25rem 0.5rem',
  155. border: 'none',
  156. borderRadius: '0.25rem',
  157. cursor: 'pointer',
  158. transition: 'background-color 0.3s',
  159. };
  160.  
  161. // Create toggle layout button
  162. const toggleLayoutButton = document.createElement('button');
  163. toggleLayoutButton.textContent = 'Toggle Layout';
  164. Object.assign(toggleLayoutButton.style, buttonStyle);
  165. toggleLayoutButton.onclick = toggleLayout;
  166.  
  167. // Create toggle right bar button
  168. const toggleRightBarButton = document.createElement('button');
  169. toggleRightBarButton.textContent = 'Toggle Right Bar';
  170. Object.assign(toggleRightBarButton.style, buttonStyle);
  171. toggleRightBarButton.onclick = toggleRightBar;
  172.  
  173. // Create toggle Ctrl+Enter button
  174. const toggleCtrlEnterButton = document.createElement('button');
  175. toggleCtrlEnterButton.textContent = isCtrlEnterEnabled ? 'Disable Ctrl+Enter' : 'Enable Ctrl+Enter';
  176. Object.assign(toggleCtrlEnterButton.style, buttonStyle);
  177. toggleCtrlEnterButton.onclick = function() {
  178. toggleCtrlEnter();
  179. toggleCtrlEnterButton.textContent = isCtrlEnterEnabled ? 'Disable Ctrl+Enter' : 'Enable Ctrl+Enter';
  180. };
  181.  
  182. // Append buttons to container
  183. buttonContainer.appendChild(toggleCtrlEnterButton);
  184. buttonContainer.appendChild(toggleLayoutButton);
  185. buttonContainer.appendChild(toggleRightBarButton);
  186.  
  187. // Append button container to body
  188. document.body.appendChild(buttonContainer);
  189.  
  190. buttonsAdded = true;
  191.  
  192. // Start interval to reapply layout every 0.1 seconds
  193. layoutInterval = setInterval(reapplyLayout, 100);
  194.  
  195. // Apply initial settings based on saved preferences
  196. reapplyLayout();
  197. if (isCtrlEnterEnabled) {
  198. enableCtrlEnter();
  199. }
  200. }
  201.  
  202. // Function to remove the buttons and clear the interval
  203. function removeButtons() {
  204. const buttonContainer = document.querySelector('#pixai-ui-helpers-buttons');
  205. if (buttonContainer) {
  206. buttonContainer.remove();
  207. buttonsAdded = false;
  208. }
  209.  
  210. if (layoutInterval) {
  211. clearInterval(layoutInterval);
  212. layoutInterval = null;
  213. }
  214. }
  215.  
  216. // Function to monitor URL changes and add/remove buttons accordingly
  217. function monitorURLChanges() {
  218. const currentURL = window.location.href;
  219.  
  220. if (currentURL.includes('/generator/')) {
  221. addButtons();
  222. } else {
  223. removeButtons();
  224. disableCtrlEnter(); // Ensure Ctrl+Enter is disabled when leaving the page
  225. }
  226. }
  227.  
  228. // Monitor for history changes (when navigating between pages using internal links)
  229. window.addEventListener('popstate', monitorURLChanges);
  230.  
  231. // Monitor for pushState changes (when navigating between pages using internal links)
  232. const originalPushState = history.pushState;
  233. history.pushState = function() {
  234. originalPushState.apply(this, arguments);
  235. monitorURLChanges();
  236. };
  237.  
  238. // Initial check to add/remove buttons based on the current page
  239. monitorURLChanges();
  240. })();