Cleanup of peeron download
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
// Peeron Socket class
|
||||
class BrickPeeronSocket extends BrickSocket {
|
||||
constructor(id, path, namespace, messages) {
|
||||
super(id, path, namespace, messages, true);
|
||||
|
||||
// Form elements (built based on the initial id)
|
||||
this.html_button = document.getElementById(id);
|
||||
this.html_files = document.getElementById(`${id}-files`);
|
||||
|
||||
if (this.html_button) {
|
||||
this.html_button.addEventListener("click", (e) => {
|
||||
this.execute();
|
||||
});
|
||||
}
|
||||
|
||||
// Setup select all button
|
||||
this.setup_select_all_button();
|
||||
|
||||
// Setup rotation buttons
|
||||
this.setup_rotation_buttons();
|
||||
|
||||
// Setup the socket
|
||||
this.setup();
|
||||
}
|
||||
|
||||
setup_select_all_button() {
|
||||
const selectAllButton = document.getElementById('peeron-select-all');
|
||||
if (selectAllButton) {
|
||||
selectAllButton.addEventListener('click', () => {
|
||||
const checkboxes = this.get_files();
|
||||
const allChecked = checkboxes.every(cb => cb.checked);
|
||||
checkboxes.forEach(cb => cb.checked = !allChecked);
|
||||
|
||||
// Update button text and icon
|
||||
if (allChecked) {
|
||||
selectAllButton.innerHTML = '<i class="ri-checkbox-multiple-line"></i> Select All';
|
||||
} else {
|
||||
selectAllButton.innerHTML = '<i class="ri-checkbox-blank-line"></i> Deselect All';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setup_rotation_buttons() {
|
||||
document.querySelectorAll('.peeron-rotate-btn').forEach(button => {
|
||||
button.addEventListener('click', (e) => {
|
||||
e.preventDefault(); // Prevent label click
|
||||
e.stopPropagation(); // Stop event bubbling
|
||||
|
||||
const targetId = button.getAttribute('data-target');
|
||||
const checkboxId = button.getAttribute('data-checkbox');
|
||||
const targetImg = document.getElementById(targetId);
|
||||
const checkbox = document.getElementById(checkboxId);
|
||||
|
||||
if (targetImg && checkbox) {
|
||||
let currentRotation = parseInt(button.getAttribute('data-rotation') || '0');
|
||||
currentRotation = (currentRotation + 90) % 360;
|
||||
|
||||
// Update image rotation
|
||||
targetImg.style.transform = `rotate(${currentRotation}deg)`;
|
||||
button.setAttribute('data-rotation', currentRotation.toString());
|
||||
|
||||
// Store rotation in checkbox data for later use
|
||||
checkbox.setAttribute('data-rotation', currentRotation.toString());
|
||||
|
||||
// Update the rotation icon to indicate current state
|
||||
const icon = button.querySelector('i');
|
||||
if (icon) {
|
||||
// Rotate the icon to match the image rotation
|
||||
icon.style.transform = `rotate(${currentRotation}deg)`;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Upon receiving a complete message
|
||||
complete(data) {
|
||||
super.complete(data);
|
||||
|
||||
// Clear progress display after completion
|
||||
if (this.html_progress_message) {
|
||||
this.html_progress_message.classList.add("d-none");
|
||||
this.html_progress_message.textContent = "";
|
||||
}
|
||||
|
||||
if (this.html_count) {
|
||||
this.html_count.classList.add("d-none");
|
||||
this.html_count.textContent = "";
|
||||
}
|
||||
|
||||
// Ensure spinner is hidden
|
||||
this.spinner(false);
|
||||
|
||||
this.toggle(true);
|
||||
}
|
||||
|
||||
// Execute the action
|
||||
execute() {
|
||||
if (!this.disabled && this.socket !== undefined && this.socket.connected) {
|
||||
this.toggle(false);
|
||||
|
||||
this.download_peeron_pages();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the list of checkboxes describing files
|
||||
get_files(checked=false) {
|
||||
let files = [];
|
||||
|
||||
if (this.html_files) {
|
||||
files = [...this.html_files.querySelectorAll('input[type="checkbox"]')];
|
||||
|
||||
if (checked) {
|
||||
files = files.filter(file => file.checked);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
// Download Peeron pages
|
||||
download_peeron_pages() {
|
||||
if (this.html_files) {
|
||||
const selectedFiles = this.get_files(true);
|
||||
|
||||
if (selectedFiles.length === 0) {
|
||||
this.fail({message: "Please select at least one page to download."});
|
||||
this.toggle(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const pages = selectedFiles.map(checkbox => ({
|
||||
page_number: checkbox.getAttribute('data-page-number'),
|
||||
thumbnail_url: checkbox.getAttribute('data-thumbnail-url'),
|
||||
image_url: checkbox.getAttribute('data-image-url'),
|
||||
alt_text: checkbox.getAttribute('data-alt-text'),
|
||||
rotation: parseInt(checkbox.getAttribute('data-rotation') || '0')
|
||||
}));
|
||||
|
||||
this.clear();
|
||||
this.spinner(true);
|
||||
|
||||
const setElement = document.querySelector('input[name="download-set"]');
|
||||
const set = setElement ? setElement.value : '';
|
||||
|
||||
this.socket.emit(this.messages.DOWNLOAD_PEERON_PAGES, {
|
||||
set: set,
|
||||
pages: pages,
|
||||
total: pages.length,
|
||||
current: 0
|
||||
});
|
||||
} else {
|
||||
this.fail({message: "Could not find the list of pages to download"});
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle clicking on the button, or sending events
|
||||
toggle(enabled) {
|
||||
super.toggle(enabled);
|
||||
|
||||
if (this.html_files) {
|
||||
this.get_files().forEach(el => el.disabled = !enabled);
|
||||
}
|
||||
|
||||
if (this.html_button) {
|
||||
this.html_button.disabled = !enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,12 @@
|
||||
{% endif %}
|
||||
{% if request.endpoint == 'set.list' %}
|
||||
<script src="{{ url_for('static', filename='scripts/sets.js') }}"></script>
|
||||
{% endif %}
|
||||
{% if request.endpoint == 'set.details' %}
|
||||
<script src="{{ url_for('static', filename='scripts/parts-bulk-operations.js') }}"></script>
|
||||
{% endif %}
|
||||
{% if request.endpoint == 'instructions.download' or request.endpoint == 'instructions.do_download' %}
|
||||
<script src="{{ url_for('static', filename='scripts/socket/peeron.js') }}"></script>
|
||||
{% endif %}
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
|
||||
@@ -1,184 +1,10 @@
|
||||
<script type="text/javascript">
|
||||
// Wait for all scripts to load, then initialize Peeron socket
|
||||
window.addEventListener('load', () => {
|
||||
// Double-check that BrickSocket is available
|
||||
if (typeof BrickSocket === 'undefined') {
|
||||
console.error('BrickSocket is not available after page load');
|
||||
return;
|
||||
}
|
||||
|
||||
// Define Peeron socket class after BrickSocket is guaranteed to be available
|
||||
class BrickPeeronSocket extends BrickSocket {
|
||||
constructor(id, path, namespace, messages) {
|
||||
super(id, path, namespace, messages, true);
|
||||
|
||||
// Form elements
|
||||
this.html_button = document.getElementById(id);
|
||||
this.html_files = document.getElementById(`${id}-files`);
|
||||
|
||||
if (this.html_button) {
|
||||
this.html_button.addEventListener("click", (e) => {
|
||||
this.execute();
|
||||
});
|
||||
}
|
||||
|
||||
// Setup select all button (now in template)
|
||||
this.setup_select_all_button();
|
||||
|
||||
// Setup rotation buttons
|
||||
this.setup_rotation_buttons();
|
||||
|
||||
// Setup the socket
|
||||
this.setup();
|
||||
}
|
||||
|
||||
setup_select_all_button() {
|
||||
const selectAllButton = document.getElementById('peeron-select-all');
|
||||
if (selectAllButton) {
|
||||
selectAllButton.addEventListener('click', () => {
|
||||
const checkboxes = this.get_files();
|
||||
const allChecked = checkboxes.every(cb => cb.checked);
|
||||
checkboxes.forEach(cb => cb.checked = !allChecked);
|
||||
|
||||
// Update button text and icon
|
||||
if (allChecked) {
|
||||
selectAllButton.innerHTML = '<i class="ri-checkbox-multiple-line"></i> Select All';
|
||||
} else {
|
||||
selectAllButton.innerHTML = '<i class="ri-checkbox-blank-line"></i> Deselect All';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setup_rotation_buttons() {
|
||||
document.querySelectorAll('.peeron-rotate-btn').forEach(button => {
|
||||
button.addEventListener('click', (e) => {
|
||||
e.preventDefault(); // Prevent label click
|
||||
e.stopPropagation(); // Stop event bubbling
|
||||
|
||||
const targetId = button.getAttribute('data-target');
|
||||
const checkboxId = button.getAttribute('data-checkbox');
|
||||
const targetImg = document.getElementById(targetId);
|
||||
const checkbox = document.getElementById(checkboxId);
|
||||
|
||||
if (targetImg && checkbox) {
|
||||
let currentRotation = parseInt(button.getAttribute('data-rotation') || '0');
|
||||
currentRotation = (currentRotation + 90) % 360;
|
||||
|
||||
// Update image rotation
|
||||
targetImg.style.transform = `rotate(${currentRotation}deg)`;
|
||||
button.setAttribute('data-rotation', currentRotation.toString());
|
||||
|
||||
// Store rotation in checkbox data for later use
|
||||
checkbox.setAttribute('data-rotation', currentRotation.toString());
|
||||
|
||||
// Update the rotation icon to indicate current state
|
||||
const icon = button.querySelector('i');
|
||||
if (icon) {
|
||||
// Rotate the icon to match the image rotation
|
||||
icon.style.transform = `rotate(${currentRotation}deg)`;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
complete(data) {
|
||||
super.complete(data);
|
||||
|
||||
// Clear progress display after completion
|
||||
if (this.html_progress_message) {
|
||||
this.html_progress_message.classList.add("d-none");
|
||||
this.html_progress_message.textContent = "";
|
||||
}
|
||||
|
||||
if (this.html_count) {
|
||||
this.html_count.classList.add("d-none");
|
||||
this.html_count.textContent = "";
|
||||
}
|
||||
|
||||
// Ensure spinner is hidden
|
||||
this.spinner(false);
|
||||
|
||||
this.toggle(true);
|
||||
}
|
||||
|
||||
execute() {
|
||||
if (!this.disabled && this.socket !== undefined && this.socket.connected) {
|
||||
this.toggle(false);
|
||||
this.download_peeron_pages();
|
||||
}
|
||||
}
|
||||
|
||||
get_files(checked=false) {
|
||||
let files = [];
|
||||
if (this.html_files) {
|
||||
files = [...this.html_files.querySelectorAll('input[type="checkbox"]')];
|
||||
if (checked) {
|
||||
files = files.filter(file => file.checked);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
download_peeron_pages() {
|
||||
if (this.html_files) {
|
||||
const selectedFiles = this.get_files(true);
|
||||
|
||||
if (selectedFiles.length === 0) {
|
||||
this.fail({message: "Please select at least one page to download."});
|
||||
this.toggle(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const pages = selectedFiles.map(checkbox => ({
|
||||
page_number: checkbox.getAttribute('data-page-number'),
|
||||
thumbnail_url: checkbox.getAttribute('data-thumbnail-url'),
|
||||
image_url: checkbox.getAttribute('data-image-url'),
|
||||
alt_text: checkbox.getAttribute('data-alt-text'),
|
||||
rotation: parseInt(checkbox.getAttribute('data-rotation') || '0')
|
||||
}));
|
||||
|
||||
this.clear();
|
||||
this.spinner(true);
|
||||
|
||||
const setElement = document.querySelector('input[name="download-set"]');
|
||||
const set = setElement ? setElement.value : '';
|
||||
|
||||
this.socket.emit(this.messages.DOWNLOAD_PEERON_PAGES, {
|
||||
set: set,
|
||||
pages: pages,
|
||||
total: pages.length,
|
||||
current: 0
|
||||
});
|
||||
} else {
|
||||
this.fail({message: "Could not find the list of pages to download"});
|
||||
}
|
||||
}
|
||||
|
||||
toggle(enabled) {
|
||||
super.toggle(enabled);
|
||||
|
||||
if (this.html_files) {
|
||||
this.get_files().forEach(el => el.disabled = !enabled);
|
||||
}
|
||||
|
||||
if (this.html_button) {
|
||||
this.html_button.disabled = !enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the socket
|
||||
try {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
new BrickPeeronSocket('peeron-download', '{{ path }}', '{{ namespace }}', {
|
||||
COMPLETE: '{{ messages['COMPLETE'] }}',
|
||||
DOWNLOAD_PEERON_PAGES: 'download_peeron_pages',
|
||||
FAIL: '{{ messages['FAIL'] }}',
|
||||
PROGRESS: '{{ messages['PROGRESS'] }}',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error initializing BrickPeeronSocket:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -58,8 +58,7 @@
|
||||
<div class="text-center position-relative">
|
||||
<div class="position-relative d-inline-block">
|
||||
<img id="peeron-img-{{ loop.index }}" src="{{ page.thumbnail_url }}" alt="{{ page.alt_text }}"
|
||||
class="img-fluid mb-2 border rounded" style="max-height: 150px; transform: rotate(0deg); transition: transform 0.3s ease;"
|
||||
data-dims-target="peeron-dims-{{ loop.index }}">
|
||||
class="img-fluid mb-2 border rounded" style="max-height: 150px; transform: rotate(0deg); transition: transform 0.3s ease;">
|
||||
<button type="button" class="btn btn-sm btn-light position-absolute top-0 end-0 p-1 me-1 mt-1 peeron-rotate-btn"
|
||||
data-target="peeron-img-{{ loop.index }}" data-checkbox="peeron-page-{{ loop.index }}" data-rotation="0"
|
||||
title="Rotate page" style="font-size: 0.7rem; line-height: 1;">
|
||||
@@ -67,7 +66,6 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="small fw-bold">Page {{ page.page_number }}</div>
|
||||
<div id="peeron-dims-{{ loop.index }}" class="small text-muted">Loading dimensions...</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
@@ -102,46 +100,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Function to show image dimensions
|
||||
function showImageDimensions(img, dimElementId) {
|
||||
const dimElement = document.getElementById(dimElementId);
|
||||
if (dimElement && img.naturalWidth && img.naturalHeight) {
|
||||
dimElement.textContent = `${img.naturalWidth} × ${img.naturalHeight} px`;
|
||||
dimElement.classList.remove('text-muted');
|
||||
dimElement.classList.add('text-info');
|
||||
} else if (dimElement) {
|
||||
dimElement.textContent = 'Dimensions unavailable';
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize dimensions for all images when page loads
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Wait for all images to load and then show dimensions
|
||||
const images = document.querySelectorAll('img[data-dims-target]');
|
||||
images.forEach(img => {
|
||||
const targetId = img.getAttribute('data-dims-target');
|
||||
|
||||
// Check if already loaded
|
||||
if (img.complete && img.naturalWidth && img.naturalHeight) {
|
||||
showImageDimensions(img, targetId);
|
||||
} else {
|
||||
// Wait for load
|
||||
img.addEventListener('load', function() {
|
||||
showImageDimensions(this, targetId);
|
||||
});
|
||||
|
||||
// Handle error case
|
||||
img.addEventListener('error', function() {
|
||||
const dimElement = document.getElementById(targetId);
|
||||
if (dimElement) {
|
||||
dimElement.textContent = 'Failed to load';
|
||||
dimElement.classList.remove('text-muted');
|
||||
dimElement.classList.add('text-danger');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user