Magnific.ai Batch Image Generator

Automates batch image generation on Magnific.ai with a sleek, toggleable popup.

  1. // ==UserScript==
  2. // @name Magnific.ai Batch Image Generator
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Automates batch image generation on Magnific.ai with a sleek, toggleable popup.
  6. // @author virtualdmns
  7. // @match https://magnific.ai/*
  8. // @run-at document-idle
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Function to create a delay
  17. function delay(ms) {
  18. return new Promise(resolve => setTimeout(resolve, ms));
  19. }
  20.  
  21. // Create the toggle button
  22. const toggleButton = document.createElement('div');
  23. toggleButton.id = 'tm-batch-toggle';
  24. toggleButton.style = `
  25. position: fixed;
  26. right: 0;
  27. top: 50%;
  28. transform: translateY(-50%);
  29. background: #444;
  30. color: #fff;
  31. padding: 10px;
  32. cursor: pointer;
  33. z-index: 10000;
  34. border-radius: 5px 0 0 5px;
  35. `;
  36. toggleButton.textContent = 'Batch';
  37. document.body.appendChild(toggleButton);
  38.  
  39. // Create the popup (hidden by default)
  40. const popup = document.createElement('div');
  41. popup.id = 'tm-batch-popup';
  42. popup.style = `
  43. position: fixed;
  44. right: 0;
  45. top: 0;
  46. width: 250px;
  47. height: 100%;
  48. background: #222;
  49. color: #fff;
  50. padding: 20px;
  51. box-shadow: -2px 0 5px rgba(0,0,0,0.5);
  52. z-index: 9999;
  53. display: none;
  54. `;
  55. popup.innerHTML = `
  56. <div style="text-align: right; margin-bottom: 10px;">
  57. <button id="tm-batch-close" style="background: none; border: none; color: #fff; font-size: 20px; cursor: pointer;">×</button>
  58. </div>
  59. <h3 style="margin: 0;">Batch Image Generator</h3>
  60. <textarea id="tm-batch-prompts" rows="10" style="width: 100%; background: #333; color: #fff; border: 1px solid #444; margin-top: 10px;"></textarea>
  61. <button id="tm-batch-start" style="background: #444; color: #fff; border: none; padding: 10px 20px; cursor: pointer; margin-top: 10px;">Start Generation</button>
  62. <div id="tm-batch-status" style="margin-top: 10px;">Status: Idle</div>
  63. `;
  64. document.body.appendChild(popup);
  65.  
  66. // Toggle the popup with the button
  67. toggleButton.addEventListener('click', () => {
  68. popup.style.display = popup.style.display === 'none' ? 'block' : 'none';
  69. });
  70.  
  71. // Close the popup with the × button
  72. document.getElementById('tm-batch-close').addEventListener('click', () => {
  73. popup.style.display = 'none';
  74. });
  75.  
  76. // Get popup elements
  77. const promptsTextarea = document.getElementById('tm-batch-prompts');
  78. const startButton = document.getElementById('tm-batch-start');
  79. const statusDiv = document.getElementById('tm-batch-status');
  80.  
  81. // Start button logic (unchanged, still spot on!)
  82. startButton.addEventListener('click', async () => {
  83. const siteTextarea = document.getElementById('text_paragraphMystic');
  84. const generateButton = document.getElementById('mystic-btn');
  85.  
  86. if (!siteTextarea || !generateButton) {
  87. statusDiv.textContent = 'Error: Site elements not found.';
  88. return;
  89. }
  90.  
  91. const prompts = promptsTextarea.value.split('\n').map(p => p.trim()).filter(p => p);
  92. if (prompts.length === 0) {
  93. statusDiv.textContent = 'Please enter some prompts.';
  94. return;
  95. }
  96.  
  97. startButton.disabled = true;
  98. statusDiv.textContent = 'Processing...';
  99.  
  100. for (let i = 0; i < prompts.length; i++) {
  101. const prompt = prompts[i];
  102. statusDiv.textContent = `Processing prompt ${i + 1} of ${prompts.length}`;
  103. siteTextarea.value = prompt;
  104. generateButton.click();
  105. await delay(1000);
  106. }
  107.  
  108. statusDiv.textContent = 'Done';
  109. startButton.disabled = false;
  110. });
  111. })();