From 98cb1ea517d469182ac746f0ded71ea8ee2c7c32 Mon Sep 17 00:00:00 2001 From: PaulVua Date: Tue, 10 Feb 2026 11:16:05 +0100 Subject: [PATCH] feat(ui): replace copy with share modal and download option - Add new "Share Report" modal with readable textarea - Add instructions to send logs to contact@aircarto.fr - Add "Download (.txt)" button to save report as file - Add "Select All" button for easy manual copy - Remove complex clipboard API code that wasn't working - Filename format: logs_nebuleair_{deviceId}_{date}.txt Co-Authored-By: Claude Opus 4.5 --- html/saraR4.html | 164 ++++++++++++++++++++++------------------------- 1 file changed, 78 insertions(+), 86 deletions(-) diff --git a/html/saraR4.html b/html/saraR4.html index cf56e5d..e8b42bd 100755 --- a/html/saraR4.html +++ b/html/saraR4.html @@ -435,12 +435,11 @@ @@ -448,6 +447,44 @@ + + +
@@ -2037,7 +2074,7 @@ async function selfTestSequence() { } } -function copySelfTestReport() { +function generateReport() { // Build formatted report let report = `=============================================================== NEBULEAIR PRO 4G - SELF TEST REPORT @@ -2120,95 +2157,50 @@ ${document.getElementById('selftest_logs').textContent} =============================================================== `; - // Copy to clipboard with fallback - copyToClipboard(report); + return report; } -function copyToClipboard(text) { - const copyBtn = document.getElementById('selfTestCopyBtn'); - const originalHtml = copyBtn.innerHTML; +function openShareReportModal() { + // Generate the report + const report = generateReport(); - // Try modern clipboard API first - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard.writeText(text).then(function() { - showCopySuccess(copyBtn, originalHtml); - }).catch(function(err) { - console.error('Clipboard API failed:', err); - fallbackCopyToClipboard(text, copyBtn, originalHtml); - }); - } else { - // Fallback for non-HTTPS or older browsers - fallbackCopyToClipboard(text, copyBtn, originalHtml); - } + // Put report in textarea + document.getElementById('shareReportText').value = report; + + // Open the share modal + const shareModal = new bootstrap.Modal(document.getElementById('shareReportModal')); + shareModal.show(); } -function fallbackCopyToClipboard(text, copyBtn, originalHtml) { - // Create a temporary textarea - const textArea = document.createElement('textarea'); - textArea.value = text; - - // Make it invisible but part of the document - textArea.style.position = 'fixed'; - textArea.style.top = '0'; - textArea.style.left = '0'; - textArea.style.width = '2em'; - textArea.style.height = '2em'; - textArea.style.padding = '0'; - textArea.style.border = 'none'; - textArea.style.outline = 'none'; - textArea.style.boxShadow = 'none'; - textArea.style.background = 'transparent'; - - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - const successful = document.execCommand('copy'); - if (successful) { - showCopySuccess(copyBtn, originalHtml); - } else { - showCopyError(copyBtn, originalHtml); - } - } catch (err) { - console.error('Fallback copy failed:', err); - showCopyError(copyBtn, originalHtml); - } - - document.body.removeChild(textArea); +function selectAllReportText() { + const textarea = document.getElementById('shareReportText'); + textarea.select(); + textarea.setSelectionRange(0, textarea.value.length); // For mobile devices } -function showCopySuccess(copyBtn, originalHtml) { - copyBtn.innerHTML = ' Copied!'; - copyBtn.classList.remove('btn-outline-primary'); - copyBtn.classList.add('btn-success'); +function downloadReport() { + const report = generateReport(); + // Create filename with device ID + const deviceId = selfTestReport.deviceId || 'unknown'; + const date = new Date().toISOString().slice(0, 10); + const filename = `logs_nebuleair_${deviceId}_${date}.txt`; + + // Create blob and download + const blob = new Blob([report], { type: 'text/plain;charset=utf-8' }); + const url = URL.createObjectURL(blob); + + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + + // Cleanup setTimeout(function() { - copyBtn.innerHTML = originalHtml; - copyBtn.classList.remove('btn-success'); - copyBtn.classList.add('btn-outline-primary'); - }, 2000); -} - -function showCopyError(copyBtn, originalHtml) { - copyBtn.innerHTML = ' Error'; - copyBtn.classList.remove('btn-outline-primary'); - copyBtn.classList.add('btn-danger'); - - setTimeout(function() { - copyBtn.innerHTML = originalHtml; - copyBtn.classList.remove('btn-danger'); - copyBtn.classList.add('btn-outline-primary'); - }, 2000); - - // Show modal with text for manual copy - alert('Could not copy automatically. The logs are displayed below - you can select and copy them manually.'); - - // Expand the logs section - const logsCollapse = document.getElementById('selftest_logs_collapse'); - if (logsCollapse && !logsCollapse.classList.contains('show')) { - new bootstrap.Collapse(logsCollapse, { toggle: true }); - } + document.body.removeChild(a); + URL.revokeObjectURL(url); + }, 100); }