Spaces:
Sleeping
Sleeping
Merge branch 'main' of github.com:Drakosfire/StoreGenerator
Browse files- block_builder.py +2 -2
- scripts.js +72 -30
- storeUI.css +35 -0
- storeUI.html +4 -2
- template_update.html +3 -3
block_builder.py
CHANGED
@@ -163,8 +163,8 @@ def build_title_block(title,description,backstory,reputation):
|
|
163 |
def build_image_block(sd_prompt, block_id):
|
164 |
image_block_html = f"""
|
165 |
<div class="block-item" data-block-id="{block_id}">
|
166 |
-
<textarea class="
|
167 |
-
hx-post="/update-stats" hx-trigger="change" hx-target="#
|
168 |
title="Storefront image description">{sd_prompt}</textarea>
|
169 |
<button class="generate-image-button" data-block-id="{block_id}">Generate Image</button>
|
170 |
<img id="generated-image-{block_id}" alt="" style="display: none; cursor: pointer;">
|
|
|
163 |
def build_image_block(sd_prompt, block_id):
|
164 |
image_block_html = f"""
|
165 |
<div class="block-item" data-block-id="{block_id}">
|
166 |
+
<textarea class="image-textarea" id="sdprompt-{block_id}"
|
167 |
+
hx-post="/update-stats" hx-trigger="change" hx-target="#sd-prompt-{block_id}" hx-swap="outerHTML"
|
168 |
title="Storefront image description">{sd_prompt}</textarea>
|
169 |
<button class="generate-image-button" data-block-id="{block_id}">Generate Image</button>
|
170 |
<img id="generated-image-{block_id}" alt="" style="display: none; cursor: pointer;">
|
scripts.js
CHANGED
@@ -5,7 +5,10 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
5 |
let blockContainerPage = document.getElementById('block-page');
|
6 |
const pageContainer = document.getElementById('pages');
|
7 |
const trashArea = document.getElementById('trashArea');
|
|
|
8 |
const resetButton = document.getElementById('resetButton');
|
|
|
|
|
9 |
let currentPage = pageContainer.querySelector('.block.monster.frame.wide');
|
10 |
const modal = document.getElementById('imageModal');
|
11 |
const modalImg = document.getElementById('modalImage');
|
@@ -35,7 +38,7 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
35 |
}
|
36 |
|
37 |
// Event delegation for image clicks
|
38 |
-
|
39 |
console.log('Click detected in blockContainer:', event.target);
|
40 |
if (event.target.tagName === 'IMG' && event.target.id.startsWith('generated-image-')) {
|
41 |
console.log('Image clicked for modal display. Image ID:', event.target.id);
|
@@ -66,7 +69,7 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
66 |
// document.getElementById('add-page-button').addEventListener('click', addPage);
|
67 |
// document.getElementById('remove-page-button').addEventListener('click', removePage);
|
68 |
|
69 |
-
fetch('
|
70 |
method: 'POST',
|
71 |
headers: {
|
72 |
'Content-Type': 'application/json'
|
@@ -91,19 +94,41 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
91 |
console.error('Error:', error);
|
92 |
});
|
93 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
var pageContainer = document.getElementById('brewRenderer');
|
97 |
-
if (pageContainer) {
|
98 |
-
var printWindow = window.open('', 'Print Preview', 'height=800,width=600');
|
99 |
-
// if (!printWindow) {
|
100 |
-
// console.error('Failed to open print window.');
|
101 |
-
// return;
|
102 |
-
// }
|
103 |
-
|
104 |
-
console.log('Page container content:', pageContainer.innerHTML); // Debugging line
|
105 |
|
106 |
-
|
107 |
<!DOCTYPE html>
|
108 |
<html lang="en">
|
109 |
<head>
|
@@ -137,15 +162,17 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
137 |
${pageContainer.innerHTML}
|
138 |
</body>
|
139 |
</html>
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
|
|
|
|
147 |
} else {
|
148 |
-
console.error('
|
149 |
}
|
150 |
};
|
151 |
|
@@ -277,11 +304,15 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
277 |
'properties-textarea',
|
278 |
'string-stat-textarea',
|
279 |
'string-action-description-textarea',
|
|
|
280 |
];
|
281 |
|
282 |
classes.forEach(className => {
|
|
|
|
|
283 |
const textareas = document.querySelectorAll(`.${className}`);
|
284 |
-
textareas.forEach(textarea => {
|
|
|
285 |
|
286 |
// Adjust height on page load
|
287 |
adjustTextareaHeight(textarea);
|
@@ -294,8 +325,7 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
294 |
});
|
295 |
}
|
296 |
|
297 |
-
|
298 |
-
initializeTextareaResizing();
|
299 |
|
300 |
async function extractBlocks() {
|
301 |
try {
|
@@ -347,10 +377,11 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
347 |
} catch (error) {
|
348 |
console.error('Error fetching and parsing template_update.html:', error);
|
349 |
}
|
|
|
350 |
}
|
351 |
|
352 |
|
353 |
-
|
354 |
if (event.target && event.target.classList.contains('generate-image-button')) {
|
355 |
const blockId = event.target.getAttribute('data-block-id');
|
356 |
generateImage(blockId);
|
@@ -359,11 +390,11 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
359 |
|
360 |
// Function to generate image
|
361 |
function generateImage(blockId) {
|
362 |
-
const sdPromptElement = document.getElementById(`
|
363 |
const imageElement = document.getElementById(`generated-image-${blockId}`);
|
364 |
|
365 |
if (!sdPromptElement) {
|
366 |
-
console.error('Element with ID
|
367 |
return;
|
368 |
}
|
369 |
|
@@ -692,11 +723,20 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
692 |
|
693 |
function removePage() {
|
694 |
const pages = pageContainer.querySelectorAll('.page');
|
695 |
-
|
696 |
if (pages.length > 1) { // Ensure at least one page remains
|
697 |
const lastPage = pages[pages.length - 1];
|
698 |
-
|
699 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
700 |
} else {
|
701 |
console.log('Cannot remove the last page.');
|
702 |
}
|
@@ -884,8 +924,10 @@ document.addEventListener("DOMContentLoaded", function() {
|
|
884 |
console.log('Reset complete, all blocks moved back to block-container');
|
885 |
initializeTextareaResizing();
|
886 |
}
|
887 |
-
|
888 |
|
|
|
|
|
|
|
889 |
blockContainer.addEventListener('dragover', handleDragOver);
|
890 |
blockContainer.addEventListener('drop', handleDrop);
|
891 |
pageContainer.addEventListener('dragover', handleDragOver);
|
|
|
5 |
let blockContainerPage = document.getElementById('block-page');
|
6 |
const pageContainer = document.getElementById('pages');
|
7 |
const trashArea = document.getElementById('trashArea');
|
8 |
+
const toggleButton = document.getElementById('toggle-text-block-button');
|
9 |
const resetButton = document.getElementById('resetButton');
|
10 |
+
const addPageButton = document.getElementById('add-page-button');
|
11 |
+
const removePageButton = document.getElementById('remove-page-button');
|
12 |
let currentPage = pageContainer.querySelector('.block.monster.frame.wide');
|
13 |
const modal = document.getElementById('imageModal');
|
14 |
const modalImg = document.getElementById('modalImage');
|
|
|
38 |
}
|
39 |
|
40 |
// Event delegation for image clicks
|
41 |
+
document.addEventListener('click', function(event) {
|
42 |
console.log('Click detected in blockContainer:', event.target);
|
43 |
if (event.target.tagName === 'IMG' && event.target.id.startsWith('generated-image-')) {
|
44 |
console.log('Image clicked for modal display. Image ID:', event.target.id);
|
|
|
69 |
// document.getElementById('add-page-button').addEventListener('click', addPage);
|
70 |
// document.getElementById('remove-page-button').addEventListener('click', removePage);
|
71 |
|
72 |
+
fetch('/process-description', {
|
73 |
method: 'POST',
|
74 |
headers: {
|
75 |
'Content-Type': 'application/json'
|
|
|
94 |
console.error('Error:', error);
|
95 |
});
|
96 |
});
|
97 |
+
document.getElementById('printButton').addEventListener('click', function() {
|
98 |
+
const newTab = window.open('', '_blank');
|
99 |
+
|
100 |
+
if (newTab) {
|
101 |
+
// Call the function to write content
|
102 |
+
window.printPageContainer(newTab);
|
103 |
+
} else {
|
104 |
+
console.error('Failed to open a new tab. It may have been blocked by the browser.');
|
105 |
+
}
|
106 |
+
});
|
107 |
|
108 |
+
function toggleAllTextBlocks() {
|
109 |
+
const pageContainer = document.querySelector('.page-container');
|
110 |
+
const textareas = pageContainer.querySelectorAll('.image-textarea');
|
111 |
+
const generateButtons = pageContainer.querySelectorAll('.generate-image-button');
|
112 |
+
|
113 |
+
let isAnyVisible = Array.from(textareas).some(textarea => textarea.style.display === 'block');
|
114 |
+
|
115 |
+
if (isAnyVisible) {
|
116 |
+
// Hide all textareas and buttons
|
117 |
+
textareas.forEach(textarea => textarea.style.display = 'none');
|
118 |
+
generateButtons.forEach(btn => btn.style.display = 'none');
|
119 |
+
document.querySelector('.toggle-text-block-button').textContent = 'Show All Image Descriptions';
|
120 |
+
} else {
|
121 |
+
// Show all textareas and buttons
|
122 |
+
textareas.forEach(textarea => textarea.style.display = 'block');
|
123 |
+
generateButtons.forEach(btn => btn.style.display = 'inline-block');
|
124 |
+
document.querySelector('.toggle-text-block-button').textContent = 'Hide All Image Descriptions';
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
window.printPageContainer = function(newTab) {
|
129 |
var pageContainer = document.getElementById('brewRenderer');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
|
131 |
+
htmlContent = `
|
132 |
<!DOCTYPE html>
|
133 |
<html lang="en">
|
134 |
<head>
|
|
|
162 |
${pageContainer.innerHTML}
|
163 |
</body>
|
164 |
</html>
|
165 |
+
`;
|
166 |
+
// Open a new tab
|
167 |
+
|
168 |
+
// Check if the new tab was blocked
|
169 |
+
if (newTab) {
|
170 |
+
// Write the HTML content to the new tab
|
171 |
+
newTab.document.open();
|
172 |
+
newTab.document.write(htmlContent);
|
173 |
+
newTab.document.close();
|
174 |
} else {
|
175 |
+
console.error('Failed to open a new tab. It may have been blocked by the browser.');
|
176 |
}
|
177 |
};
|
178 |
|
|
|
304 |
'properties-textarea',
|
305 |
'string-stat-textarea',
|
306 |
'string-action-description-textarea',
|
307 |
+
'image-textarea'
|
308 |
];
|
309 |
|
310 |
classes.forEach(className => {
|
311 |
+
console.log('Initializing textareas for class:', className);
|
312 |
+
console.log(document.querySelectorAll(`.${className}`));
|
313 |
const textareas = document.querySelectorAll(`.${className}`);
|
314 |
+
textareas.forEach(textarea => {
|
315 |
+
console.log('Textarea found:', textarea);
|
316 |
|
317 |
// Adjust height on page load
|
318 |
adjustTextareaHeight(textarea);
|
|
|
325 |
});
|
326 |
}
|
327 |
|
328 |
+
|
|
|
329 |
|
330 |
async function extractBlocks() {
|
331 |
try {
|
|
|
377 |
} catch (error) {
|
378 |
console.error('Error fetching and parsing template_update.html:', error);
|
379 |
}
|
380 |
+
initializeTextareaResizing();
|
381 |
}
|
382 |
|
383 |
|
384 |
+
document.addEventListener('click', function(event) {
|
385 |
if (event.target && event.target.classList.contains('generate-image-button')) {
|
386 |
const blockId = event.target.getAttribute('data-block-id');
|
387 |
generateImage(blockId);
|
|
|
390 |
|
391 |
// Function to generate image
|
392 |
function generateImage(blockId) {
|
393 |
+
const sdPromptElement = document.getElementById(`sdprompt-${blockId}`);
|
394 |
const imageElement = document.getElementById(`generated-image-${blockId}`);
|
395 |
|
396 |
if (!sdPromptElement) {
|
397 |
+
console.error('Element with ID sdprompt not found');
|
398 |
return;
|
399 |
}
|
400 |
|
|
|
723 |
|
724 |
function removePage() {
|
725 |
const pages = pageContainer.querySelectorAll('.page');
|
726 |
+
|
727 |
if (pages.length > 1) { // Ensure at least one page remains
|
728 |
const lastPage = pages[pages.length - 1];
|
729 |
+
const blocks = lastPage.querySelectorAll('.block-content'); // Check for blocks inside the last page
|
730 |
+
|
731 |
+
if (blocks.length > 0) {
|
732 |
+
// If blocks are present, block the removal and display a warning
|
733 |
+
console.log(`Cannot remove page with ID: ${lastPage.id} because it contains ${blocks.length} block(s).`);
|
734 |
+
alert(`Cannot remove this page because it contains ${blocks.length} block(s). Please remove the blocks first.`);
|
735 |
+
} else {
|
736 |
+
// If no blocks are present, allow removal
|
737 |
+
pageContainer.removeChild(lastPage);
|
738 |
+
console.log(`Page removed with ID: ${lastPage.id}`);
|
739 |
+
}
|
740 |
} else {
|
741 |
console.log('Cannot remove the last page.');
|
742 |
}
|
|
|
924 |
console.log('Reset complete, all blocks moved back to block-container');
|
925 |
initializeTextareaResizing();
|
926 |
}
|
|
|
927 |
|
928 |
+
addPageButton.addEventListener('click', addPage);
|
929 |
+
removePageButton.addEventListener('click', removePage);
|
930 |
+
toggleButton.addEventListener('click', toggleAllTextBlocks);
|
931 |
blockContainer.addEventListener('dragover', handleDragOver);
|
932 |
blockContainer.addEventListener('drop', handleDrop);
|
933 |
pageContainer.addEventListener('dragover', handleDragOver);
|
storeUI.css
CHANGED
@@ -470,6 +470,41 @@
|
|
470 |
resize: none; /* Prevents the textarea from being manually resizable */
|
471 |
overflow: hidden; /* Hide scrollbars */
|
472 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
473 |
|
474 |
.block.monster.frame.wide {
|
475 |
column-count: inherit;
|
|
|
470 |
resize: none; /* Prevents the textarea from being manually resizable */
|
471 |
overflow: hidden; /* Hide scrollbars */
|
472 |
}
|
473 |
+
|
474 |
+
.image-textarea {
|
475 |
+
width: 100%;
|
476 |
+
height: 16px;
|
477 |
+
font-size: 14px;
|
478 |
+
font-weight: 400;
|
479 |
+
line-height: 16px;
|
480 |
+
margin-bottom: 0;
|
481 |
+
box-sizing: border-box;
|
482 |
+
border: 0;
|
483 |
+
font-family: "ScalySansRemake";
|
484 |
+
vertical-align: baseline;
|
485 |
+
margin: 0;
|
486 |
+
padding: 0;
|
487 |
+
overflow-wrap: break-word;
|
488 |
+
text-rendering: optimizeLegibility;
|
489 |
+
background: none;
|
490 |
+
resize: none; /* Prevents the textarea from being manually resizable */
|
491 |
+
overflow: hidden; /* Hide scrollbars */
|
492 |
+
}
|
493 |
+
|
494 |
+
.page-container .image-textarea {
|
495 |
+
display: none; /* Hidden by default when in .page-container */
|
496 |
+
}
|
497 |
+
|
498 |
+
.page-container .block-content:hover .image-textarea {
|
499 |
+
display: block; /* Show when hovering over .block-content */
|
500 |
+
}
|
501 |
+
.page-container .generate-image-button {
|
502 |
+
display: none; /* Hidden by default when in .page-container */
|
503 |
+
}
|
504 |
+
|
505 |
+
.page-container .block-content:hover .generate-image-button {
|
506 |
+
display: inline-block; /* Show the button on hover */
|
507 |
+
}
|
508 |
|
509 |
.block.monster.frame.wide {
|
510 |
column-count: inherit;
|
storeUI.html
CHANGED
@@ -29,9 +29,11 @@
|
|
29 |
hx-target="#user-description" hx-swap="outerHTML"
|
30 |
title="As much or as little description as you want to provide. You can provide specific employees, inventory etc">A very standard gear store run by a fae potted plant named Gorgeous</textarea>
|
31 |
<button id="submitDescription">Submit</button>
|
32 |
-
<button id="
|
|
|
|
|
33 |
<button id="resetButton">Reset</button>
|
34 |
-
<button
|
35 |
<div class="brewRenderer" id="brewRenderer">
|
36 |
|
37 |
<div class="pages" id="pages">
|
|
|
29 |
hx-target="#user-description" hx-swap="outerHTML"
|
30 |
title="As much or as little description as you want to provide. You can provide specific employees, inventory etc">A very standard gear store run by a fae potted plant named Gorgeous</textarea>
|
31 |
<button id="submitDescription">Submit</button>
|
32 |
+
<button id="toggle-text-block-button">Toggle Image Descriptions</button>
|
33 |
+
<button id="add-page-button">Add New Page</button>
|
34 |
+
<button id="remove-page-button">Remove Last Page</button>
|
35 |
<button id="resetButton">Reset</button>
|
36 |
+
<button id="printButton">Open Tab to print</button>
|
37 |
<div class="brewRenderer" id="brewRenderer">
|
38 |
|
39 |
<div class="pages" id="pages">
|
template_update.html
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
</div>
|
10 |
|
11 |
<div class="block-item" data-block-id="1" data-page-id="block-container" draggable="true">
|
12 |
-
<textarea class="
|
13 |
<button class="generate-image-button" data-block-id="1">Generate Image</button>
|
14 |
<img id="generated-image-1" alt="" style="display: none; cursor: pointer;">
|
15 |
</div>
|
@@ -75,7 +75,7 @@
|
|
75 |
</div>
|
76 |
|
77 |
<div class="block-item" data-block-id="3" data-page-id="block-container" draggable="true">
|
78 |
-
<textarea class="
|
79 |
<button class="generate-image-button" data-block-id="3">Generate Image</button>
|
80 |
<img id="generated-image-3" alt="" style="display: none; cursor: pointer;">
|
81 |
</div>
|
@@ -124,7 +124,7 @@
|
|
124 |
</div>
|
125 |
|
126 |
<div class="block-item" data-block-id="5" data-page-id="block-container" draggable="true">
|
127 |
-
<textarea class="
|
128 |
<button class="generate-image-button" data-block-id="5">Generate Image</button>
|
129 |
<img id="generated-image-5" alt="" style="display: none; cursor: pointer;">
|
130 |
</div>
|
|
|
9 |
</div>
|
10 |
|
11 |
<div class="block-item" data-block-id="1" data-page-id="block-container" draggable="true">
|
12 |
+
<textarea class="image-textarea" id="user-storefront-prompt-1" hx-post="/update-stats" hx-trigger="change" hx-target="#user-sd-prompt" hx-swap="outerHTML" title="Storefront image description" style="height: 80px;">A highly detailed fantasy painting of a curious sentient potted plant in a vibrant gear shop. The plant has phosphorescent leaves and delicate, intricate roots. The shop is filled with glowing flora, magical tools, and adventure gear. The background shows enchanted trees intertwined with the walls and ceiling.</textarea>
|
13 |
<button class="generate-image-button" data-block-id="1">Generate Image</button>
|
14 |
<img id="generated-image-1" alt="" style="display: none; cursor: pointer;">
|
15 |
</div>
|
|
|
75 |
</div>
|
76 |
|
77 |
<div class="block-item" data-block-id="3" data-page-id="block-container" draggable="true">
|
78 |
+
<textarea class="image-textarea" id="user-storefront-prompt-3" hx-post="/update-stats" hx-trigger="change" hx-target="#user-sd-prompt" hx-swap="outerHTML" title="Storefront image description" style="height: 48px;">A highly detailed fantasy drawing of a sentient potted plant with glowing tendrils, set in an enchanting gear shop filled with vibrant flora and a myriad of magical items.</textarea>
|
79 |
<button class="generate-image-button" data-block-id="3">Generate Image</button>
|
80 |
<img id="generated-image-3" alt="" style="display: none; cursor: pointer;">
|
81 |
</div>
|
|
|
124 |
</div>
|
125 |
|
126 |
<div class="block-item" data-block-id="5" data-page-id="block-container" draggable="true">
|
127 |
+
<textarea class=""image-textarea"" id="user-storefront-prompt-5" hx-post="/update-stats" hx-trigger="change" hx-target="#user-sd-prompt" hx-swap="outerHTML" title="Storefront image description" style="height: 49px;">A highly detailed fantasy image of a half-elf shopkeeper with forest-green eyes and flower-adorned hair, set in a magical gear shop filled with glowing plants and enchanted equipment.</textarea>
|
128 |
<button class="generate-image-button" data-block-id="5">Generate Image</button>
|
129 |
<img id="generated-image-5" alt="" style="display: none; cursor: pointer;">
|
130 |
</div>
|