Files
AIO_3D_Print_Web_Platform/app/templates/printer/control.html
2026-04-13 16:32:30 +08:00

87 lines
3.7 KiB
HTML

{% extends 'base.html' %}
{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2"><i class="bi bi-arrows-move text-primary me-2"></i>{{ _('Printer Control') }}</h1>
</div>
{% if error %}
<div class="alert alert-danger" role="alert">
<i class="bi bi-exclamation-triangle me-2"></i>{{ error }}
</div>
{% else %}
<div class="row row-cols-1 row-cols-lg-2 g-4">
<!-- Webcam Stream -->
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-header bg-dark text-light fw-bold rounded-top">
<i class="bi bi-camera-video me-1"></i>{{ _('Live Webcam') }}
</div>
<div class="card-body p-0 ratio ratio-16x9">
<img src="{{ webcam_url }}" alt="{{ _('Loading webcam stream...') }}" class="w-100 h-100 object-fit-cover">
</div>
</div>
</div>
<!-- Motion Control -->
<div class="col">
<div class="card shadow-sm h-100">
<div class="card-header bg-light fw-bold text-secondary">
<i class="bi bi-dpad me-1"></i>{{ _('Basic Control') }}
</div>
<div class="card-body text-center d-flex flex-column justify-content-center align-items-center">
<!-- Home button -->
<button class="btn btn-lg btn-primary rounded-circle mb-4 shadow" style="width: 80px; height: 80px;" onclick="sendCommand('home')" title="{{ _('Home All Axes') }}">
<i class="bi bi-house-door fs-2"></i>
</button>
<div class="text-muted mb-4">{{ _('Home All Axes') }} (G28)</div>
<!-- Quick macros -->
<div class="d-flex gap-3 justify-content-center flex-wrap w-100">
<button class="btn btn-outline-danger flex-fill shadow-sm py-3" onclick="sendCommand('pause')" title="{{ _('Pause/Resume Print') }}">
<i class="bi bi-pause-circle fs-4 d-block mb-1"></i>{{ _('Pause') }}
</button>
<button class="btn btn-outline-warning flex-fill shadow-sm py-3" onclick="sendCommand('cancel')" title="{{ _('Cancel Print') }}">
<i class="bi bi-stop-circle fs-4 d-block mb-1"></i>{{ _('Cancel') }}
</button>
</div>
</div>
</div>
</div>
</div>
<script>
function sendCommand(cmdName) {
if ((cmdName === 'cancel' || cmdName === 'home') && !confirm("Are you sure you want to perform this action?")) {
return;
}
fetch('{{ url_for("printer.api_command") }}', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({command: cmdName})
})
.then(r => r.json())
.then(data => {
if(data.success) {
flashMessage("success", "Command " + cmdName + " sent.");
} else {
flashMessage("danger", "Control failed: " + data.error);
}
})
.catch(err => {
flashMessage("danger", "Network Error: " + err);
});
}
function flashMessage(type, text) {
const container = document.querySelector('.toast-container');
if(!container) return alert(text);
const toast = document.createElement('div');
toast.className = `toast align-items-center border-0 bg-${type} text-white show`;
toast.innerHTML = `<div class="d-flex"><div class="toast-body fw-medium">${text}</div><button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button></div>`;
container.appendChild(toast);
setTimeout(() => toast.remove(), 4000);
}
</script>
{% endif %}
{% endblock %}