VHF/UHF modes

This commit is contained in:
Szymon Porwolik
2025-11-02 16:49:04 +01:00
parent c15944fa7e
commit 919c2da0a6
2 changed files with 223 additions and 55 deletions

View File

@@ -533,40 +533,45 @@
<div class="menu-bar">
<!-- First Row: Band Filters, Mode Filters, and Continent Filters -->
<div class="d-flex flex-wrap align-items-center gap-2 mb-2">
<!-- Band Filter Buttons -->
<div class="d-flex flex-wrap gap-2 align-items-center">
<!-- MF Band -->
<div class="btn-group flex-shrink-0" role="group">
<button class="btn btn-sm btn-primary" type="button" id="toggle160mFilter" title="<?= __("Toggle 160m band filter"); ?>">160m</button>
</div>
<!-- HF Bands -->
<div class="btn-group flex-shrink-0" role="group">
<button class="btn btn-sm btn-primary" type="button" id="toggle80mFilter" title="<?= __("Toggle 80m band filter"); ?>">80m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle60mFilter" title="<?= __("Toggle 60m band filter"); ?>">60m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle40mFilter" title="<?= __("Toggle 40m band filter"); ?>">40m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle30mFilter" title="<?= __("Toggle 30m band filter"); ?>">30m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle20mFilter" title="<?= __("Toggle 20m band filter"); ?>">20m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle17mFilter" title="<?= __("Toggle 17m band filter"); ?>">17m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle15mFilter" title="<?= __("Toggle 15m band filter"); ?>">15m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle12mFilter" title="<?= __("Toggle 12m band filter"); ?>">12m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle10mFilter" title="<?= __("Toggle 10m band filter"); ?>">10m</button>
</div>
<!-- Band Filter Buttons -->
<div class="d-flex flex-wrap gap-2 align-items-center">
<?php
// Generate band filter buttons grouped by band group
// Keep MF and HF as individual buttons, group VHF/UHF/SHF together
$vhfUhfShfButtons = [];
<!-- VHF Bands -->
<div class="btn-group flex-shrink-0" role="group">
<button class="btn btn-sm btn-primary" type="button" id="toggle6mFilter" title="<?= __("Toggle 6m band filter"); ?>">6m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle4mFilter" title="<?= __("Toggle 4m band filter"); ?>">4m</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle2mFilter" title="<?= __("Toggle 2m band filter"); ?>">2m</button>
</div>
foreach ($bands as $key => $bandgroup) {
$groupKey = strtoupper($key);
<!-- UHF Bands -->
<div class="btn-group flex-shrink-0" role="group">
<button class="btn btn-sm btn-primary" type="button" id="toggle70cmFilter" title="<?= __("Toggle 70cm band filter"); ?>">70cm</button>
<button class="btn btn-sm btn-primary" type="button" id="toggle23cmFilter" title="<?= __("Toggle 23cm band filter"); ?>">23cm</button>
</div>
</div>
// Collect VHF, UHF, SHF for later grouping
if (in_array($groupKey, ['VHF', 'UHF', 'SHF'])) {
$vhfUhfShfButtons[$groupKey] = $groupKey;
} else {
// MF and HF bands get individual buttons in their own groups
echo '<div class="btn-group flex-shrink-0" role="group">';
foreach ($bandgroup as $band) {
$bandId = str_replace('.', '', $band); // Remove dots for ID (e.g., 2.5mm -> 25mm)
echo '<button class="btn btn-sm btn-primary" type="button" id="toggle' . $bandId . 'Filter" title="' . __("Toggle") . ' ' . $band . ' ' . __("band filter") . '">' . $band . '</button>';
}
echo '</div>' . "\n";
}
}
<!-- Spacer to push modes and continents to the right -->
// Output VHF/UHF/SHF as one button group
if (!empty($vhfUhfShfButtons)) {
echo '<div class="btn-group flex-shrink-0" role="group">';
foreach ($vhfUhfShfButtons as $groupKey) {
echo '<button class="btn btn-sm btn-primary" type="button" id="toggle' . $groupKey . 'Filter" title="' . __("Toggle") . ' ' . $groupKey . ' ' . __("bands filter") . '">' . $groupKey . '</button>';
}
echo '</div>' . "\n";
}
// Add SAT button
echo '<div class="btn-group flex-shrink-0" role="group">';
echo '<button class="btn btn-sm btn-primary" type="button" id="toggleSATFilter" title="' . __("Toggle SAT band filter") . '">SAT</button>';
echo '</div>' . "\n";
?>
</div> <!-- Spacer to push modes and continents to the right -->
<div class="flex-grow-1"></div>
@@ -685,15 +690,16 @@
<select id="band" class="form-select form-select-sm" name="band" multiple="multiple">
<option value="All" selected><?= __("All"); ?></option>
<?php foreach ($bands as $key => $bandgroup) {
echo '<optgroup label="' . strtoupper($key) . '">';
foreach ($bandgroup as $band) {
echo '<option value="' . $band . '"';
echo '>' . $band . '</option>' . "\n";
}
echo '</optgroup>';
echo '<optgroup label="' . strtoupper($key) . '">';
foreach ($bandgroup as $band) {
echo '<option value="' . $band . '"';
echo '>' . $band . '</option>' . "\n";
}
?>
</select>
echo '</optgroup>';
}
?>
<option value="SAT">SAT</option>
</select>
</div>
</div>

View File

@@ -180,9 +180,8 @@ $(function() {
// Band filter buttons - green if All, orange if specific band, blue if not selected
// Always update colors, even when CAT Control is enabled (so users can see which band is active)
let bandButtons = ['#toggle160mFilter', '#toggle80mFilter', '#toggle60mFilter', '#toggle40mFilter', '#toggle30mFilter',
'#toggle20mFilter', '#toggle17mFilter', '#toggle15mFilter', '#toggle12mFilter', '#toggle10mFilter',
'#toggle6mFilter', '#toggle4mFilter', '#toggle2mFilter', '#toggle70cmFilter', '#toggle23cmFilter'];
let bandIds = ['160m', '80m', '60m', '40m', '30m', '20m', '17m', '15m', '12m', '10m', '6m', '4m', '2m', '70cm', '23cm'];
'#toggle20mFilter', '#toggle17mFilter', '#toggle15mFilter', '#toggle12mFilter', '#toggle10mFilter'];
let bandIds = ['160m', '80m', '60m', '40m', '30m', '20m', '17m', '15m', '12m', '10m'];
bandButtons.forEach((btnId, index) => {
let $btn = $(btnId);
@@ -194,6 +193,39 @@ $(function() {
} else {
$btn.addClass('btn-primary');
}
});
// Band group buttons (VHF, UHF, SHF, SAT)
let groupButtons = [
{ id: '#toggleVHFFilter', group: 'VHF' },
{ id: '#toggleUHFFilter', group: 'UHF' },
{ id: '#toggleSHFFilter', group: 'SHF' },
{ id: '#toggleSATFilter', band: 'SAT' }
];
groupButtons.forEach(btn => {
let $btn = $(btn.id);
$btn.removeClass('btn-primary btn-warning btn-success');
if (allBandsSelected) {
$btn.addClass('btn-success');
} else {
let isActive = false;
if (btn.group) {
// Check if any band in the group is selected
const groupBands = getBandsInGroup(btn.group);
isActive = groupBands.some(b => bandValues.includes(b));
} else if (btn.band) {
// For SAT, check directly
isActive = bandValues.includes(btn.band);
}
if (isActive) {
$btn.addClass('btn-warning');
} else {
$btn.addClass('btn-primary');
}
}
}); // Mode buttons - green if All, orange if selected, blue if not
let modeButtons = [
{ id: '#toggleCwFilter', mode: 'cw', icon: 'fa-wave-square' },
@@ -669,6 +701,9 @@ $(function() {
if (reqFlag === 'notworked') {
if (single.worked_call) return; // Reject if already worked
}
if (reqFlag === 'Contest') {
if (!single.dxcc_spotted || !single.dxcc_spotted.isContest) return;
}
}
} // Apply CWN (Confirmed/Worked/New) filter
let passesCwnFilter = cwnStatuses.includes('All');
@@ -683,8 +718,8 @@ $(function() {
// Apply band filter (client-side for multi-select)
let passesBandFilter = bands.includes('All');
if (!passesBandFilter) {
let freq_khz = single.frequency;
let spot_band = getBandFromFrequency(freq_khz);
// Check if spot has band field (for SAT), otherwise determine from frequency
let spot_band = single.band || getBandFromFrequency(single.frequency);
passesBandFilter = bands.includes(spot_band);
}
if (!passesBandFilter) return;
@@ -982,7 +1017,7 @@ $(function() {
cachedSpotData.forEach((spot) => {
// Count by band
let freq_khz = spot.frequency;
let band = getBandFromFrequency(freq_khz);
let band = spot.band || getBandFromFrequency(freq_khz);
if (band) {
bandCounts[band] = (bandCounts[band] || 0) + 1;
totalSpots++;
@@ -995,14 +1030,28 @@ $(function() {
}
});
// Update each band button badge
const bandButtons = [
// Count band groups (VHF, UHF, SHF, SAT)
let groupCounts = {
'VHF': 0,
'UHF': 0,
'SHF': 0,
'SAT': 0
};
Object.keys(bandCounts).forEach(band => {
let group = getBandGroup(band);
if (group) {
groupCounts[group] += bandCounts[band];
}
});
// Update individual MF/HF band button badges
const mfHfBands = [
'160m', '80m', '60m', '40m', '30m', '20m',
'17m', '15m', '12m', '10m', '6m', '4m', '2m',
'70cm', '23cm'
'17m', '15m', '12m', '10m'
];
bandButtons.forEach(band => {
mfHfBands.forEach(band => {
let count = bandCounts[band] || 0;
let $badge = $('#toggle' + band + 'Filter .band-count-badge');
if ($badge.length === 0) {
@@ -1014,6 +1063,19 @@ $(function() {
}
});
// Update band group button badges (VHF, UHF, SHF, SAT)
['VHF', 'UHF', 'SHF', 'SAT'].forEach(group => {
let count = groupCounts[group] || 0;
let $badge = $('#toggle' + group + 'Filter .band-count-badge');
if ($badge.length === 0) {
// Badge doesn't exist yet, create it
$('#toggle' + group + 'Filter').append(' <span class="badge bg-secondary band-count-badge">' + count + '</span>');
} else {
// Update existing badge
$badge.text(count);
}
});
// Update mode button badges
const modeButtons = ['Cw', 'Digi', 'Phone'];
modeButtons.forEach(mode => {
@@ -1082,11 +1144,6 @@ $(function() {
table.page.len(50);
if (dxspots.length > 0) {
// Filter out spots with no frequency or frequency = 0
dxspots = dxspots.filter(spot => {
return spot.frequency && parseFloat(spot.frequency) > 0;
});
dxspots.sort(SortByQrg); // Sort by frequency
cachedSpotData = dxspots;
} else {
@@ -1180,6 +1237,30 @@ $(function() {
return 'All';
}
// Map individual bands to their band groups (VHF, UHF, SHF)
function getBandGroup(band) {
const VHF_BANDS = ['6m', '4m', '2m'];
const UHF_BANDS = ['1.25m', '70cm', '33cm', '23cm'];
const SHF_BANDS = ['13cm', '9cm', '6cm', '3cm', '1.25cm', '6mm', '4mm', '2.5mm', '2mm', '1mm'];
if (VHF_BANDS.includes(band)) return 'VHF';
if (UHF_BANDS.includes(band)) return 'UHF';
if (SHF_BANDS.includes(band)) return 'SHF';
if (band === 'SAT') return 'SAT';
return null; // MF/HF bands don't have groups
}
// Get all bands in a band group
function getBandsInGroup(group) {
const BAND_GROUPS = {
'VHF': ['6m', '4m', '2m'],
'UHF': ['1.25m', '70cm', '33cm', '23cm'],
'SHF': ['13cm', '9cm', '6cm', '3cm', '1.25cm', '6mm', '4mm', '2.5mm', '2mm', '1mm'],
'SAT': ['SAT']
};
return BAND_GROUPS[group] || [];
}
// Categorize mode as phone/cw/digi for filtering
function getModeCategory(mode) {
if (!mode) return null;
@@ -2018,6 +2099,87 @@ $(function() {
applyFilters(false);
});
// Band group filter buttons (VHF, UHF, SHF, SAT)
$('#toggleVHFFilter').on('click', function() {
let currentValues = $('#band').val() || [];
if (currentValues.includes('All')) currentValues = currentValues.filter(v => v !== 'All');
const vhfBands = getBandsInGroup('VHF');
const hasAllVHF = vhfBands.every(b => currentValues.includes(b));
if (hasAllVHF) {
// Remove all VHF bands
currentValues = currentValues.filter(v => !vhfBands.includes(v));
if (currentValues.length === 0) currentValues = ['All'];
} else {
// Add all VHF bands
vhfBands.forEach(b => {
if (!currentValues.includes(b)) currentValues.push(b);
});
}
$('#band').val(currentValues).trigger('change');
syncQuickFilterButtons();
applyFilters(false);
});
$('#toggleUHFFilter').on('click', function() {
let currentValues = $('#band').val() || [];
if (currentValues.includes('All')) currentValues = currentValues.filter(v => v !== 'All');
const uhfBands = getBandsInGroup('UHF');
const hasAllUHF = uhfBands.every(b => currentValues.includes(b));
if (hasAllUHF) {
// Remove all UHF bands
currentValues = currentValues.filter(v => !uhfBands.includes(v));
if (currentValues.length === 0) currentValues = ['All'];
} else {
// Add all UHF bands
uhfBands.forEach(b => {
if (!currentValues.includes(b)) currentValues.push(b);
});
}
$('#band').val(currentValues).trigger('change');
syncQuickFilterButtons();
applyFilters(false);
});
$('#toggleSHFFilter').on('click', function() {
let currentValues = $('#band').val() || [];
if (currentValues.includes('All')) currentValues = currentValues.filter(v => v !== 'All');
const shfBands = getBandsInGroup('SHF');
const hasAllSHF = shfBands.every(b => currentValues.includes(b));
if (hasAllSHF) {
// Remove all SHF bands
currentValues = currentValues.filter(v => !shfBands.includes(v));
if (currentValues.length === 0) currentValues = ['All'];
} else {
// Add all SHF bands
shfBands.forEach(b => {
if (!currentValues.includes(b)) currentValues.push(b);
});
}
$('#band').val(currentValues).trigger('change');
syncQuickFilterButtons();
applyFilters(false);
});
$('#toggleSATFilter').on('click', function() {
let currentValues = $('#band').val() || [];
if (currentValues.includes('All')) currentValues = currentValues.filter(v => v !== 'All');
if (currentValues.includes('SAT')) {
currentValues = currentValues.filter(v => v !== 'SAT');
if (currentValues.length === 0) currentValues = ['All'];
} else {
currentValues.push('SAT');
}
$('#band').val(currentValues).trigger('change');
syncQuickFilterButtons();
applyFilters(false);
});
// Continent filter buttons (spotter's continent - de continent)
$('#toggleAfricaFilter').on('click', function() {
let currentValues = $('#decontSelect').val() || [];