corrected all bugs

This commit is contained in:
2026-01-11 15:33:44 +01:00
parent 46ee44c6c9
commit 9837657dd9
10 changed files with 992 additions and 497 deletions

View File

@@ -2,6 +2,7 @@
import { api } from '../lib/api.js';
export let status;
export let flexradio = null;
$: connected = status?.connected || false;
$: frequency = status?.frequency || 0;
@@ -13,6 +14,21 @@
$: elementLengths = status?.element_lengths || [];
$: firmwareVersion = status ? `${status.firmware_major}.${status.firmware_minor}` : '0.0';
// FlexRadio interlock
$: interlockConnected = flexradio?.connected || false;
$: interlockState = flexradio?.interlock_state || null;
$: interlockColor = getInterlockColor(interlockState);
function getInterlockColor(state) {
switch(state) {
case 'READY': return '#4caf50';
case 'NOT_READY': return '#f44336';
case 'PTT_REQUESTED': return '#ffc107';
case 'TRANSMITTING': return '#ff9800';
default: return 'rgba(255, 255, 255, 0.3)';
}
}
// Band names mapping - VL2.3 covers 6M to 40M only
// Band 0=6M, 1=10M, 2=12M, 3=15M, 4=17M, 5=20M, 6=30M, 7=40M
const bandNames = [
@@ -102,7 +118,7 @@
await api.ultrabeam.setAutoTrack(autoTrackEnabled, autoTrackThreshold);
} catch (err) {
console.error('Failed to update auto-track:', err);
alert('Failed to update auto-track settings');
// Removed alert popup - check console for errors
}
}
@@ -114,7 +130,7 @@
await api.ultrabeam.retract();
} catch (err) {
console.error('Failed to retract:', err);
alert('Failed to retract');
// Removed alert popup - check console for errors
}
}
@@ -122,11 +138,11 @@
try {
const newLength = elementLengths[selectedElement] + elementAdjustment;
// TODO: Add API call when backend supports it
alert(`Would adjust element ${selectedElement} by ${elementAdjustment}mm to ${newLength}mm`);
// Removed alert popup - check console for errors
elementAdjustment = 0;
} catch (err) {
console.error('Failed to adjust element:', err);
alert('Failed to adjust element');
// Removed alert popup - check console for errors
}
}
@@ -137,7 +153,17 @@
<div class="card">
<div class="card-header">
<h2>Ultrabeam VL2.3</h2>
<span class="status-dot" class:disconnected={!connected}></span>
<div class="header-right">
{#if interlockConnected && interlockState}
<div class="interlock-badge" style="border-color: {interlockColor}; color: {interlockColor}">
{interlockState === 'READY' ? '🔓 TX OK' :
interlockState === 'NOT_READY' ? '🔒 TX Block' :
interlockState === 'PTT_REQUESTED' ? '⏳ PTT' :
interlockState === 'TRANSMITTING' ? '📡 TX' : '❓'}
</div>
{/if}
<span class="status-dot" class:disconnected={!connected}></span>
</div>
</div>
<div class="metrics">
@@ -176,30 +202,31 @@
{/each}
</select>
</div>
<div class="direction-buttons">
<button
class="dir-btn normal"
class:active={targetDirection === 0}
on:click={() => { targetDirection = 0; setDirection(); }}
>
Normal
</button>
<button
class="dir-btn rotate180"
class:active={targetDirection === 1}
on:click={() => { targetDirection = 1; setDirection(); }}
>
180°
</button>
<button
class="dir-btn bidir"
class:active={targetDirection === 2}
on:click={() => { targetDirection = 2; setDirection(); }}
>
Bi-Dir
</button>
</div>
</div>
<!-- Direction buttons on separate line -->
<div class="direction-buttons">
<button
class="dir-btn"
class:active={targetDirection === 0}
on:click={() => { targetDirection = 0; setDirection(); }}
>
Normal
</button>
<button
class="dir-btn"
class:active={targetDirection === 1}
on:click={() => { targetDirection = 1; setDirection(); }}
>
180°
</button>
<button
class="dir-btn"
class:active={targetDirection === 2}
on:click={() => { targetDirection = 2; setDirection(); }}
>
Bi-Dir
</button>
</div>
</div>
@@ -310,6 +337,24 @@
border-bottom: 2px solid rgba(79, 195, 247, 0.3);
}
.header-right {
display: flex;
align-items: center;
gap: 12px;
}
.interlock-badge {
padding: 4px 10px;
border-radius: 12px;
border: 2px solid;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
background: rgba(0, 0, 0, 0.3);
transition: all 0.2s;
}
h2 {
margin: 0;
font-size: 20px;
@@ -447,267 +492,76 @@
.direction-buttons {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-top: 12px;
gap: 12px;
margin-top: 16px;
}
.dir-btn {
padding: 14px 20px;
border: none;
border-radius: 10px;
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
cursor: pointer;
transition: all 0.3s;
color: white;
letter-spacing: 0.5px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.dir-btn.normal {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.dir-btn.normal:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.5);
}
.dir-btn.normal.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 0 25px rgba(102, 126, 234, 0.8), 0 6px 20px rgba(102, 126, 234, 0.5);
transform: translateY(-2px);
}
.dir-btn.rotate180 {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}
.dir-btn.rotate180:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(245, 87, 108, 0.5);
}
.dir-btn.rotate180.active {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
box-shadow: 0 0 25px rgba(245, 87, 108, 0.8), 0 6px 20px rgba(245, 87, 108, 0.5);
transform: translateY(-2px);
}
.dir-btn.bidir {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
.dir-btn.bidir:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(79, 172, 254, 0.5);
}
.dir-btn.bidir.active {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
box-shadow: 0 0 25px rgba(79, 172, 254, 0.8), 0 6px 20px rgba(79, 172, 254, 0.5);
transform: translateY(-2px);
}
.freq-control {
display: grid;
grid-template-columns: 2fr 1fr auto;
gap: 12px;
align-items: end;
}
.input-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.input-group label {
font-size: 12px;
color: rgba(255, 255, 255, 0.7);
text-transform: uppercase;
letter-spacing: 0.5px;
}
input[type="number"],
select {
background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(79, 195, 247, 0.3);
padding: 12px 16px;
border: 2px solid rgba(79, 195, 247, 0.3);
border-radius: 8px;
padding: 10px 12px;
color: #fff;
font-size: 16px;
transition: all 0.2s;
}
input[type="number"]:focus,
select:focus {
outline: none;
border-color: #4fc3f7;
box-shadow: 0 0 12px rgba(79, 195, 247, 0.3);
}
/* Buttons */
button {
padding: 12px 20px;
border-radius: 8px;
border: none;
font-size: 13px;
font-weight: 600;
font-size: 14px;
text-transform: uppercase;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 8px;
justify-content: center;
color: rgba(255, 255, 255, 0.7);
background: rgba(79, 195, 247, 0.08);
letter-spacing: 0.5px;
}
.btn-primary {
background: linear-gradient(135deg, #4fc3f7 0%, #03a9f4 100%);
color: #fff;
box-shadow: 0 4px 16px rgba(79, 195, 247, 0.4);
.dir-btn:hover {
border-color: rgba(79, 195, 247, 0.6);
color: rgba(255, 255, 255, 0.9);
background: rgba(79, 195, 247, 0.15);
transform: translateY(-1px);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(79, 195, 247, 0.6);
}
.btn-danger {
background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
color: #fff;
box-shadow: 0 4px 16px rgba(244, 67, 54, 0.4);
width: 100%;
}
.btn-danger:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(244, 67, 54, 0.6);
}
.btn-caution {
background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%);
color: #fff;
box-shadow: 0 4px 16px rgba(255, 167, 38, 0.4);
width: 100%;
}
.btn-caution:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(255, 167, 38, 0.6);
}
.btn-toggle {
background: rgba(79, 195, 247, 0.1);
.dir-btn.active {
border-color: #4fc3f7;
color: #4fc3f7;
border: 1px solid rgba(79, 195, 247, 0.3);
padding: 6px 12px;
font-size: 12px;
}
.btn-toggle.active {
background: rgba(79, 195, 247, 0.2);
box-shadow: 0 0 20px rgba(79, 195, 247, 0.4);
font-weight: 700;
}
.icon {
font-size: 16px;
}
/* Progress */
/* Progress Section */
.progress-section {
background: rgba(15, 23, 42, 0.4);
padding: 12px;
border-radius: 12px;
border: 1px solid rgba(255, 193, 7, 0.3);
background: rgba(79, 195, 247, 0.1);
padding: 16px;
border-radius: 8px;
border: 2px solid rgba(79, 195, 247, 0.3);
margin-top: 16px;
}
.progress-section h3 {
margin: 0 0 12px 0;
font-size: 14px;
color: #4fc3f7;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.progress-bar {
width: 100%;
height: 24px;
background: rgba(15, 23, 42, 0.8);
border-radius: 12px;
height: 20px;
background: rgba(15, 23, 42, 0.6);
border-radius: 10px;
overflow: hidden;
margin: 12px 0;
border: 1px solid rgba(79, 195, 247, 0.3);
position: relative;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #4fc3f7 0%, #66bb6a 100%);
background: linear-gradient(90deg, #4fc3f7, #03a9f4);
transition: width 0.3s ease;
box-shadow: 0 0 12px rgba(79, 195, 247, 0.6);
border-radius: 10px;
}
.progress-text {
text-align: center;
color: #4fc3f7;
font-weight: 600;
}
/* Elements */
.elements-section {
background: rgba(15, 23, 42, 0.4);
padding: 12px;
border-radius: 12px;
border: 1px solid rgba(79, 195, 247, 0.2);
}
.elements-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 12px;
}
.element-item {
background: rgba(15, 23, 42, 0.6);
padding: 12px;
border-radius: 8px;
border: 1px solid rgba(79, 195, 247, 0.2);
text-align: center;
}
.element-label {
font-size: 11px;
color: rgba(255, 255, 255, 0.6);
margin-bottom: 4px;
}
.element-value {
font-size: 16px;
font-weight: 600;
color: #66bb6a;
}
/* Calibration */
.calibration-section {
background: rgba(255, 152, 0, 0.05);
padding: 12px;
border-radius: 12px;
border: 1px solid rgba(255, 152, 0, 0.3);
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.calibration-controls {
display: flex;
flex-direction: column;
gap: 10px;
}
.warning-text {
margin: 0;
padding: 12px;
background: rgba(255, 152, 0, 0.1);
border-radius: 8px;
border-left: 3px solid #ffa726;
color: #ffa726;
font-size: 13px;
color: rgba(255, 255, 255, 0.8);
margin-top: 8px;
}
.actions {
@@ -715,13 +569,4 @@
gap: 12px;
}
@media (max-width: 768px) {
.freq-control {
grid-template-columns: 1fr;
}
.elements-grid {
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}
}
</style>