refactor: replace feature globals with typed services
This commit is contained in:
@@ -50,13 +50,21 @@ interface VirtualChannelBridge {
|
||||
applyLocalTunedFrequency?: (frequencyHz: number) => void;
|
||||
setRigFrequency?: (frequencyHz: number) => void;
|
||||
refreshFreqDisplay?: () => void;
|
||||
vchanTakeSchedulerControl?: () => Promise<void>;
|
||||
vchanInterceptMode?: (mode: string) => Promise<boolean>;
|
||||
vchanInterceptBandwidth?: (bandwidthHz: number) => Promise<boolean>;
|
||||
vchanHandleSession?: (data: string) => void;
|
||||
vchanHandleChannels?: (data: string) => void;
|
||||
vchanApplyCapabilities?: (capabilities: { filter_controls?: boolean } | null) => void;
|
||||
vchanIsOnVirtual?: () => boolean;
|
||||
trx?: { modules?: { vchan?: VirtualChannelService } };
|
||||
}
|
||||
|
||||
interface VirtualChannelService {
|
||||
readonly channels: readonly VirtualChannel[];
|
||||
readonly activeId: string | null;
|
||||
activeChannel(): VirtualChannel | null;
|
||||
applyCapabilities(capabilities: { filter_controls?: boolean } | null): void;
|
||||
handleSession(data: string): void;
|
||||
handleChannels(data: string): void;
|
||||
isOnVirtual(): boolean;
|
||||
interceptMode(mode: string): Promise<boolean>;
|
||||
interceptBandwidth(bandwidthHz: number): Promise<boolean>;
|
||||
takeSchedulerControl(): Promise<void>;
|
||||
releaseToScheduler(): Promise<void>;
|
||||
}
|
||||
const vchanWindow = window as unknown as VirtualChannelBridge;
|
||||
|
||||
@@ -169,7 +177,6 @@ async function vchanTakeSchedulerControl() {
|
||||
console.error("scheduler control takeover failed", e);
|
||||
}
|
||||
}
|
||||
vchanWindow.vchanTakeSchedulerControl = vchanTakeSchedulerControl;
|
||||
|
||||
// Called by app.js when the SSE `session` event arrives.
|
||||
function vchanHandleSession(data: string): void {
|
||||
@@ -208,8 +215,6 @@ function vchanHandleChannels(data: string): void {
|
||||
console.warn("vchan: bad channels event", e);
|
||||
}
|
||||
}
|
||||
vchanWindow.vchanHandleSession = vchanHandleSession;
|
||||
vchanWindow.vchanHandleChannels = vchanHandleChannels;
|
||||
|
||||
function vchanRender() {
|
||||
const picker = document.getElementById("vchan-picker");
|
||||
@@ -388,7 +393,6 @@ function vchanApplyCapabilities(caps: { filter_controls?: boolean } | null): voi
|
||||
picker.style.display = (caps && caps.filter_controls) ? "" : "none";
|
||||
vchanRenderSchedulerRelease();
|
||||
}
|
||||
vchanWindow.vchanApplyCapabilities = vchanApplyCapabilities;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Freq / mode interception + UI accent
|
||||
@@ -399,7 +403,6 @@ function vchanIsOnVirtual(): boolean {
|
||||
if (!vchanActiveId || vchanChannels.length === 0) return false;
|
||||
return vchanActiveId !== vchanChannels[0]?.id;
|
||||
}
|
||||
vchanWindow.vchanIsOnVirtual = vchanIsOnVirtual;
|
||||
|
||||
function vchanActiveChannel(): VirtualChannel | null {
|
||||
return vchanChannels.find(c => c.id === vchanActiveId) || null;
|
||||
@@ -554,18 +557,34 @@ async function vchanSetChannelMode(mode: string): Promise<void> {
|
||||
// Called by app.js (applyModeFromPicker) and bookmarks.js (bmApply) before
|
||||
// sending /set_mode to the server. Returns true if the change was handled
|
||||
// by the virtual channel (caller should skip the server request).
|
||||
vchanWindow.vchanInterceptMode = async function(mode: string) {
|
||||
async function vchanInterceptMode(mode: string): Promise<boolean> {
|
||||
if (!vchanIsOnVirtual()) return false;
|
||||
await vchanSetChannelMode(mode);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
// Called by app.js bandwidth setters before sending /set_bandwidth to the
|
||||
// server. Returns true if the change was handled by the virtual channel.
|
||||
vchanWindow.vchanInterceptBandwidth = async function(bwHz: number) {
|
||||
async function vchanInterceptBandwidth(bwHz: number): Promise<boolean> {
|
||||
if (!vchanIsOnVirtual()) return false;
|
||||
await vchanSetChannelBandwidth(bwHz);
|
||||
return true;
|
||||
}
|
||||
|
||||
vchanWindow.trx ??= {};
|
||||
vchanWindow.trx.modules ??= {};
|
||||
vchanWindow.trx.modules.vchan = {
|
||||
get channels() { return vchanChannels; },
|
||||
get activeId() { return vchanActiveId; },
|
||||
activeChannel: vchanActiveChannel,
|
||||
applyCapabilities: vchanApplyCapabilities,
|
||||
handleSession: vchanHandleSession,
|
||||
handleChannels: vchanHandleChannels,
|
||||
isOnVirtual: vchanIsOnVirtual,
|
||||
interceptMode: vchanInterceptMode,
|
||||
interceptBandwidth: vchanInterceptBandwidth,
|
||||
takeSchedulerControl: vchanTakeSchedulerControl,
|
||||
releaseToScheduler: vchanToggleSchedulerRelease,
|
||||
};
|
||||
|
||||
// Wrap setRigFrequency (defined in app.js, loaded before this file) so that
|
||||
|
||||
Reference in New Issue
Block a user