@@ -37,11 +37,23 @@
|
||||
<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>
|
||||
<!-- Motion Controls -->
|
||||
<div class="d-flex gap-4 justify-content-center mb-4 w-100">
|
||||
<!-- Home button -->
|
||||
<div>
|
||||
<button class="btn btn-lg btn-primary rounded-circle shadow mb-2" 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 small">{{ _('Home All Axes') }}<br>(G28)</div>
|
||||
</div>
|
||||
<!-- Auto Level button -->
|
||||
<div>
|
||||
<button class="btn btn-lg btn-info rounded-circle shadow mb-2 text-white" style="width: 80px; height: 80px;" onclick="sendCommand('auto_level')" title="{{ _('Auto Leveling') }}">
|
||||
<i class="bi bi-grid-3x3 fs-2"></i>
|
||||
</button>
|
||||
<div class="text-muted small">{{ _('Auto Leveling') }}<br>(G29)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick macros -->
|
||||
<div class="d-flex gap-3 justify-content-center flex-wrap w-100">
|
||||
@@ -59,7 +71,7 @@
|
||||
|
||||
<script>
|
||||
function sendCommand(cmdName) {
|
||||
if (cmdName === 'cancel' || cmdName === 'home') {
|
||||
if (cmdName === 'cancel' || cmdName === 'home' || cmdName === 'auto_level') {
|
||||
window.customConfirm("{{ _('Are you sure you want to perform this action?') }}", () => doSendCommand(cmdName));
|
||||
} else {
|
||||
doSendCommand(cmdName);
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<div id="file-{{ f.id }}" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center py-3 transition-style">
|
||||
<div class="me-auto text-truncate" style="max-width: 80%;">
|
||||
<h6 class="mb-1"><i class="bi bi-file-earmark-code text-primary me-2"></i>{{ f.name }}</h6>
|
||||
<small class="text-muted d-block">{{ _('Size:') }} {{ f.size }} bytes, {{ _('Time:') }} {{ f.gcodeAnalysis.estimatedPrintTime if f.gcodeAnalysis else 'Unknown' }}s</small>
|
||||
<small class="text-muted d-block pb-1">{{ _('Size:') }} {{ f.size | filesizeformat }}, {% if f.meta_print_time and f.meta_print_time != '-' %}{{ _('Estimated Time:') }} {{ f.meta_print_time }}{% else %}{{ _('Time:') }} {{ f.gcodeAnalysis.estimatedPrintTime if f.gcodeAnalysis else 'Unknown' }}s{% endif %}</small>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{ url_for('main.preview_gcode', file_id=f.id) }}" class="btn btn-sm btn-outline-info rounded-pill px-3 shadow-sm me-2"><i class="bi bi-eye me-1"></i>{{ _('Preview') }}</a>
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between text-muted small mt-2">
|
||||
<span><strong>{{ _('Print Time:') }}</strong> <span id="job-print-time">{{ job.get('progress', {}).get('printTime', 0) if job else 0 }}</span>s</span>
|
||||
<span><strong>{{ _('Time Left:') }}</strong> <span id="job-time-left">{{ job.get('progress', {}).get('printTimeLeft', 0) if job else 0 }}</span>s</span>
|
||||
<span><strong>{{ _('Print Time:') }}</strong> <span id="job-print-time"></span></span>
|
||||
<span><strong>{{ _('Time Left:') }}</strong> <span id="job-time-left"></span></span>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 gap-2 d-flex">
|
||||
@@ -81,6 +81,22 @@
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
function formatTime(seconds) {
|
||||
if (!seconds && seconds !== 0) return '0{{ _("s") }}';
|
||||
seconds = Math.round(seconds);
|
||||
let d = Math.floor(seconds / 86400);
|
||||
let h = Math.floor((seconds % 86400) / 3600);
|
||||
let m = Math.floor((seconds % 3600) / 60);
|
||||
let s = Math.floor(seconds % 60);
|
||||
|
||||
let res = [];
|
||||
if (d > 0) res.push(d + '{{ _("d") }}');
|
||||
if (h > 0 || d > 0) res.push(h + '{{ _("h") }}');
|
||||
if (m > 0 || h > 0 || d > 0) res.push(m + '{{ _("m") }}');
|
||||
if (s > 0 || res.length === 0) res.push(s + '{{ _("s") }}');
|
||||
return res.join(' ');
|
||||
}
|
||||
|
||||
function updateStatus() {
|
||||
fetch('{{ url_for("printer.api_status_data") }}')
|
||||
.then(res => res.json())
|
||||
@@ -105,8 +121,8 @@ function updateStatus() {
|
||||
document.getElementById('job-progress-bar').style.width = progress + '%';
|
||||
document.getElementById('job-progress-bar').setAttribute('aria-valuenow', progress);
|
||||
document.getElementById('job-progress-text').innerText = progress.toFixed(1) + '%';
|
||||
document.getElementById('job-print-time').innerText = data.job.progress ? (data.job.progress.printTime || 0) : 0;
|
||||
document.getElementById('job-time-left').innerText = data.job.progress ? (data.job.progress.printTimeLeft || 0) : 0;
|
||||
document.getElementById('job-print-time').innerText = formatTime(data.job.progress ? data.job.progress.printTime : 0);
|
||||
document.getElementById('job-time-left').innerText = formatTime(data.job.progress ? data.job.progress.printTimeLeft : 0);
|
||||
} else {
|
||||
jobCard.style.display = 'none';
|
||||
}
|
||||
@@ -115,6 +131,8 @@ function updateStatus() {
|
||||
.catch(err => console.error("Error fetching status:", err));
|
||||
}
|
||||
{% if not error %}
|
||||
// Run once immediately to populate initial data consistently
|
||||
updateStatus();
|
||||
setInterval(updateStatus, 1000);
|
||||
{% endif %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user