feat(cluster): the spot list size is a setting
The list is a ring buffer that held a thousand spots, and on a busy evening a thousand arrive in a couple of minutes. So the buffer decided how long a spot lived, and the spot LIFETIME setting never got the chance to expire anything: fifteen minutes meant nothing when the oldest spot was pushed out after two. Now settable (Preferences → Cluster, beside the lifetime, since between them they decide the same thing), 100 to 10 000. The ceiling is a real limit rather than a round number: every spot is matched against the worked index and the alert rules, and is a row the cluster grid and every open band map re-render.
This commit is contained in:
@@ -58,7 +58,7 @@ import {
|
||||
GetFolderSync, SaveFolderSync, PickFolderSyncFolder, GetFolderSyncStatus, SyncFolderNow,
|
||||
GetRelayAuto, SaveRelayAuto, GetStationDevices,
|
||||
GetAwardDefs, GetTrackedAwards, SaveTrackedAwards,
|
||||
GetBandOpenSettings, SaveBandOpenSettings, GetGridScopeSettings, SaveGridScopeSettings, GetPSKReporterStatus, GetChaseNewGrids, SetChaseNewGrids, GetChaseNew, SetChaseNew, GetGridCacheStatus, GetLinkedAmps, SetLinkedAmps, GetSpotTTLMinutes, SetSpotTTLMinutes,
|
||||
GetBandOpenSettings, SaveBandOpenSettings, GetGridScopeSettings, SaveGridScopeSettings, GetPSKReporterStatus, GetChaseNewGrids, SetChaseNewGrids, GetChaseNew, SetChaseNew, GetGridCacheStatus, GetLinkedAmps, SetLinkedAmps, GetSpotTTLMinutes, SetSpotTTLMinutes, GetSpotMax, SetSpotMax,
|
||||
} from '../../wailsjs/go/main/App';
|
||||
import type { profile as profileModels } from '../../wailsjs/go/models';
|
||||
import type { LookupSettingsForm, StationSettingsForm, ListsSettingsForm, ModePresetForm } from '@/types';
|
||||
@@ -1942,6 +1942,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
const [chaseNew, setChaseNew] = useState(false);
|
||||
const [spotTTL, setSpotTTL] = useState(0);
|
||||
const [spotTTLText, setSpotTTLText] = useState('0');
|
||||
const [spotMaxText, setSpotMaxText] = useState('1000');
|
||||
const [gridStat, setGridStat] = useState<any>(null);
|
||||
const [pskrStatus, setPskrStatus] = useState<any>(null);
|
||||
const saveBandOpen = async (next: any) => {
|
||||
@@ -1955,6 +1956,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
try { setChaseNew(await GetChaseNew()); } catch { /* defaults stand */ }
|
||||
try { setLinkedAmps((await GetLinkedAmps()) ?? []); } catch { /* defaults stand */ }
|
||||
try { const n = await GetSpotTTLMinutes(); setSpotTTL(n); setSpotTTLText(String(n)); } catch { /* defaults stand */ }
|
||||
try { const n = await GetSpotMax(); setSpotMaxText(String(n)); } catch { /* defaults stand */ }
|
||||
})();
|
||||
// Poll the feed while the panel is open: a live count is the only thing that
|
||||
// distinguishes "connected" from "connected and receiving nothing".
|
||||
@@ -4973,6 +4975,28 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
}} />
|
||||
<span className="text-xs text-muted-foreground">{t('clu.spotTtlHint')}</span>
|
||||
</div>
|
||||
{/* The list size, beside the lifetime because between them they decide
|
||||
the same thing: whichever runs out first removes the spot. */}
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<span className="text-sm">{t('clu.spotMax')}</span>
|
||||
<div className="inline-flex rounded-md border border-border overflow-hidden text-xs">
|
||||
{[500, 1000, 2500, 5000].map((v) => (
|
||||
<button key={v} type="button"
|
||||
onClick={() => { setSpotMaxText(String(v)); SetSpotMax(v).catch(() => {}); }}
|
||||
className={cn('px-2.5 py-1.5 font-medium', Number(spotMaxText) === v ? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted')}>
|
||||
{v}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<Input className="h-8 w-24" value={spotMaxText}
|
||||
onChange={(e) => {
|
||||
const raw = e.target.value.replace(/[^0-9]/g, '');
|
||||
setSpotMaxText(raw);
|
||||
const n = parseInt(raw, 10);
|
||||
if (Number.isFinite(n) && n > 0) SetSpotMax(Math.min(10000, n)).catch(() => {});
|
||||
}} />
|
||||
<span className="text-xs text-muted-foreground">{t('clu.spotMaxHint')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-border/60 pt-3 space-y-2">
|
||||
|
||||
Reference in New Issue
Block a user