From faf084ddfce3d6548c8ad9e266a161fd67fe4f7e Mon Sep 17 00:00:00 2001 From: Gregory Salaun Date: Thu, 6 Aug 2026 17:29:00 +0200 Subject: [PATCH] =?UTF-8?q?feat(awards):=20follow-list=20picker=20in=20Set?= =?UTF-8?q?tings=20=E2=86=92=20Awards,=20filter=20the=20Awards=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New per-profile "tracked awards" selection: Settings → Awards (under User configuration) is a two-column transfer list — every defined award on the left, the ones you follow on the right, click to move either way. The Awards tab's list is narrowed to the followed set; an empty set means "show them all" so the tab is never blank. Backend: app_awards_tracked.go adds keyAwardsTracked (per-profile JSON array of award codes) with GetTrackedAwards/SaveTrackedAwards; saving emits awards:tracked-changed so the Awards tab re-filters live. Award definitions stay global — only the follow selection is per profile. --- app_awards_tracked.go | 57 +++++++++++++++ changelog.json | 6 +- frontend/src/components/AwardsPanel.tsx | 22 ++++-- frontend/src/components/SettingsModal.tsx | 86 ++++++++++++++++++++++- frontend/src/lib/i18n.tsx | 2 + frontend/wailsjs/go/main/App.d.ts | 4 ++ frontend/wailsjs/go/main/App.js | 8 +++ 7 files changed, 177 insertions(+), 8 deletions(-) create mode 100644 app_awards_tracked.go diff --git a/app_awards_tracked.go b/app_awards_tracked.go new file mode 100644 index 0000000..c696ba5 --- /dev/null +++ b/app_awards_tracked.go @@ -0,0 +1,57 @@ +package main + +import ( + "encoding/json" + "fmt" + "strings" + + wruntime "github.com/wailsapp/wails/v2/pkg/runtime" +) + +// keyAwardsTracked holds the PER-PROFILE list of award codes the operator wants +// to follow (JSON array of award.Def.Code). Award definitions themselves are +// global (keyAwardDefs, shared across profiles), but WHICH awards a station +// tracks is a per-profile choice — a DX profile follows DXCC/WPX, a POTA profile +// follows POTA/WWFF. An empty/unset list means "track them all" so the Awards +// tab is never blank before the operator has picked anything. +const keyAwardsTracked = "awards.tracked" + +// GetTrackedAwards returns the active profile's followed award codes. An empty +// slice means the operator has not narrowed the list — the Awards tab then shows +// every award. +func (a *App) GetTrackedAwards() ([]string, error) { + out := []string{} + if a.settings == nil { + return out, nil + } + s, _ := a.settings.Get(a.ctx, keyAwardsTracked) + if strings.TrimSpace(s) == "" { + return out, nil + } + if err := json.Unmarshal([]byte(s), &out); err != nil { + return []string{}, nil + } + return out, nil +} + +// SaveTrackedAwards persists the followed award codes for the active profile and +// notifies the Awards tab to re-filter its list. Codes are stored verbatim; the +// Awards tab intersects them with the live award definitions, so a code that no +// longer exists is simply ignored (not an error). +func (a *App) SaveTrackedAwards(codes []string) error { + if a.settings == nil { + return fmt.Errorf("db not initialized") + } + if codes == nil { + codes = []string{} + } + b, err := json.Marshal(codes) + if err != nil { + return err + } + if err := a.settings.Set(a.ctx, keyAwardsTracked, string(b)); err != nil { + return err + } + wruntime.EventsEmit(a.ctx, "awards:tracked-changed") + return nil +} diff --git a/changelog.json b/changelog.json index 282cc45..78eaf09 100644 --- a/changelog.json +++ b/changelog.json @@ -11,7 +11,8 @@ "Stats slot drill-down: the pop-up listing the QSOs behind a band/mode square looks tidier (banded rows, cleaner header), and you can now click a callsign in it to open that QSO for editing.", "DCU-1 rotor support: OpsLog can now steer controllers that speak the Hy-Gain DCU-1 protocol (RotorCard DXA for Yaesu DXA rotors, Idiom Press Rotor-EZ, Green Heron) over their COM port or a serial-over-IP bridge.", "Motorized antenna: Settings → Antenna now has a Covered bands selector (40 m–6 m) instead of a min/max range, for both the Ultrabeam and the SteppIR. Tick only the bands your antenna does — untick one you can't (e.g. 30 m without its extension) while keeping the rest — and OpsLog leaves the antenna put on every other band. This overrides an unreliable controller, so 80 m no longer clamps the elements down to 30 m. Existing range settings migrate automatically.", - "Motorized antenna: on a band you did not tick in Covered bands, OpsLog no longer inhibits FlexRadio transmit for \"antenna moving\". Un-ticking a band now means hands off completely — no tuning and no TX block — so working it on another antenna is never gagged." + "Motorized antenna: on a band you did not tick in Covered bands, OpsLog no longer inhibits FlexRadio transmit for \"antenna moving\". Un-ticking a band now means hands off completely — no tuning and no TX block — so working it on another antenna is never gagged.", + "Awards: a new Settings → Awards picker (under User configuration) lets you choose which awards to follow — a two-column list, all awards on the left, the ones you track on the right. The Awards tab then shows only those you follow (per profile; leave the right side empty to show them all)." ], "fr": [ "Édition de QSO : ajout du bouton QRZ ↗ à côté de l'indicatif, comme dans le formulaire de saisie — un clic ouvre le profil qrz.com de la station.", @@ -22,7 +23,8 @@ "Détail d’un slot Stats : la fenêtre listant les QSO derrière une case bande/mode est plus soignée (lignes alternées, en-tête plus propre), et vous pouvez maintenant cliquer un indicatif pour ouvrir ce QSO en édition.", "Prise en charge des rotors DCU-1 : OpsLog pilote désormais les contrôleurs parlant le protocole Hy-Gain DCU-1 (RotorCard DXA pour rotors Yaesu DXA, Idiom Press Rotor-EZ, Green Heron) via leur port COM ou un pont série-sur-IP.", "Antenne motorisée : Réglages → Antenne propose désormais un sélecteur Bandes couvertes (40 m–6 m) au lieu d'une plage min/max, pour l'Ultrabeam comme pour la SteppIR. Coche seulement les bandes que fait ton antenne — décoche celle que tu ne fais pas (p. ex. le 30 m sans son extension) en gardant les autres — et OpsLog laisse l'antenne en place sur toutes les autres. Ceci prime sur un contrôleur peu fiable : le 80 m ne replie plus les éléments sur le 30 m. Les anciens réglages de plage sont migrés automatiquement.", - "Antenne motorisée : sur une bande non cochée dans Bandes couvertes, OpsLog n'inhibe plus l'émission du FlexRadio pour « antenne en mouvement ». Décocher une bande signifie désormais ne plus y toucher du tout — ni accord ni blocage TX — pour ne jamais couper le trafic sur une autre antenne." + "Antenne motorisée : sur une bande non cochée dans Bandes couvertes, OpsLog n'inhibe plus l'émission du FlexRadio pour « antenne en mouvement ». Décocher une bande signifie désormais ne plus y toucher du tout — ni accord ni blocage TX — pour ne jamais couper le trafic sur une autre antenne.", + "Diplômes : un nouveau sélecteur Réglages → Diplômes (dans Configuration utilisateur) permet de choisir les diplômes à suivre — une liste à deux colonnes, tous les diplômes à gauche, ceux que tu suis à droite. L'onglet Awards n'affiche alors que ceux-là (par profil ; laisse la colonne de droite vide pour tous les afficher)." ] }, { diff --git a/frontend/src/components/AwardsPanel.tsx b/frontend/src/components/AwardsPanel.tsx index d55a3c1..1434a5d 100644 --- a/frontend/src/components/AwardsPanel.tsx +++ b/frontend/src/components/AwardsPanel.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo, useState } from 'react'; import { Award as AwardIcon, RefreshCw, Loader2, Search, Pencil, X, Grid3x3, List, BarChart3, AlertTriangle, ChevronUp, ChevronDown } from 'lucide-react'; -import { GetAwardDefs, GetAward, AwardCellQSOs, GetAwardStats, AwardMissingQSOs, ListAwardReferences, AssignAwardRefToQSOs, RescanAwards } from '../../wailsjs/go/main/App'; +import { GetAwardDefs, GetAward, AwardCellQSOs, GetAwardStats, AwardMissingQSOs, ListAwardReferences, AssignAwardRefToQSOs, RescanAwards, GetTrackedAwards } from '../../wailsjs/go/main/App'; +import { EventsOn } from '../../wailsjs/runtime/runtime'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; @@ -137,13 +138,20 @@ export function AwardsPanel({ onEditQSO, onAwardsChanged }: { onEditQSO?: (id: n } } - // Load the award list (no QSO scan), then compute only the first award. + // Load the award list (no QSO scan), then compute only the first award. The + // list is narrowed to the awards the operator follows (Settings → Awards); an + // empty follow-set means "show them all" so the tab is never blank. async function loadList() { try { - const defs = ((await GetAwardDefs()) ?? []) as any[]; - const list: AwardListItem[] = defs + const [defs, tracked] = await Promise.all([ + GetAwardDefs().then((d) => (d ?? []) as any[]), + GetTrackedAwards().then((t) => (t ?? []) as string[]).catch(() => [] as string[]), + ]); + const follow = new Set(tracked); + let list: AwardListItem[] = defs .map((d) => ({ code: d.code, name: d.name, valid: d.valid, bands: d.valid_bands ?? [], emission: d.emission ?? [] })) .sort((a, b) => a.code.localeCompare(b.code)); + if (follow.size > 0) list = list.filter((a) => follow.has(a.code)); setAwardList(list); const first = list.find((a) => a.code === selected) ?? list[0]; if (first) compute(first.code); @@ -152,6 +160,12 @@ export function AwardsPanel({ onEditQSO, onAwardsChanged }: { onEditQSO?: (id: n } } useEffect(() => { loadList(); }, []); + // Re-filter when the operator changes their followed awards in Settings. + useEffect(() => { + const off = EventsOn('awards:tracked-changed', () => { loadList(); }); + return () => { off(); }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const current = byCode[`${selected}|${modeFilter}`]; // Recompute when the mode class changes: the bands, counts and confirmations diff --git a/frontend/src/components/SettingsModal.tsx b/frontend/src/components/SettingsModal.tsx index 8bbf3c2..540ba15 100644 --- a/frontend/src/components/SettingsModal.tsx +++ b/frontend/src/components/SettingsModal.tsx @@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { ArrowDown, ArrowUp, ArrowLeft, ArrowRight, Copy, Plus, Star, StarOff, Trash2, ChevronDown, ChevronRight, - User, Database, Radio, Cog, Server, Award, Antenna as AntennaIcon, + User, Database, Radio, Cog, Server, Antenna as AntennaIcon, Compass, Wifi, Construction, UploadCloud, Loader2, FolderOpen, Play, Power, Check, Pencil, } from 'lucide-react'; import { @@ -50,6 +50,7 @@ import { GetFlexState, GetFlexBandAntennas, SaveFlexBandAntennas, GetFlexBandPower, SaveFlexBandPower, GetADIFMonitor, SaveADIFMonitor, PickADIFMonitorFile, GetRelayAuto, SaveRelayAuto, GetStationDevices, + GetAwardDefs, GetTrackedAwards, SaveTrackedAwards, } from '../../wailsjs/go/main/App'; import type { profile as profileModels } from '../../wailsjs/go/models'; import type { LookupSettingsForm, StationSettingsForm, ListsSettingsForm, ModePresetForm } from '@/types'; @@ -254,6 +255,7 @@ function buildTree(flexAvailable: boolean, t: (k: string) => string): TreeNode[] { kind: 'item', label: t('sec.profiles'), id: 'profiles' }, { kind: 'item', label: t('sec.operating'), id: 'operating' }, { kind: 'item', label: t('sec.confirmations'), id: 'confirmations' }, + { kind: 'item', label: t('sec.awards'), id: 'awards' }, { kind: 'item', label: t('sec.external'), id: 'external-services' }, ], }, @@ -944,6 +946,86 @@ function FlexDiscover({ onPick }: { onPick: (ip: string, port: number) => void } ); } +// AwardsSelectionPanel is a two-column transfer list: every defined award on the +// left, the ones the operator follows on the right. The Awards tab shows only the +// followed set (empty = all). Per-profile, saved immediately (local SQLite). +function AwardsSelectionPanel({ profile }: { profile?: { name?: string; callsign?: string } }) { + const { t } = useI18n(); + const [all, setAll] = useState<{ code: string; name: string }[]>([]); + const [tracked, setTracked] = useState([]); + const [err, setErr] = useState(''); + const [q, setQ] = useState(''); + + useEffect(() => { + (async () => { + try { + const [defs, tr] = await Promise.all([ + GetAwardDefs().then((d) => (d ?? []) as any[]), + GetTrackedAwards().then((v) => (v ?? []) as string[]).catch(() => [] as string[]), + ]); + setAll(defs.map((d) => ({ code: d.code, name: d.name })).sort((a, b) => a.code.localeCompare(b.code))); + setTracked(tr); + } catch (e: any) { setErr(String(e?.message ?? e)); } + })(); + }, []); + + async function persist(next: string[]) { + setTracked(next); + try { await SaveTrackedAwards(next); } catch (e: any) { setErr(String(e?.message ?? e)); } + } + const trackedSet = new Set(tracked); + const byCode = new Map(all.map((a) => [a.code, a] as const)); + const needle = q.trim().toLowerCase(); + const available = all.filter((a) => !trackedSet.has(a.code) + && (needle === '' || `${a.code} ${a.name}`.toLowerCase().includes(needle))); + const trackedItems = tracked.map((c) => byCode.get(c)).filter(Boolean) as { code: string; name: string }[]; + + const Row = ({ a, arrow, onClick }: { a: { code: string; name: string }; arrow: 'right' | 'left'; onClick: () => void }) => ( + + ); + + return ( +
+ + + {err &&
{err}
} +
+
+
+ {t('awards.available')} ({available.length}) + +
+
+ setQ(e.target.value)} placeholder={t('awards.search')} className="h-8" /> +
+
+ {available.map((a) => persist([...tracked, a.code])} />)} + {available.length === 0 &&
{t('awards.allTracked')}
} +
+
+
+
+ {t('awards.followed')} ({tracked.length}) + +
+
+ {trackedItems.map((a) => persist(tracked.filter((c) => c !== a.code))} />)} + {tracked.length === 0 &&
{t('awards.noneFollowed')}
} +
+
+
+
+ ); +} + function ComingSoon({ id, icon: Icon }: { id: SectionId; icon?: any }) { const label = SECTION_LABELS[id] ?? id; const IconCmp = Icon ?? Construction; @@ -5822,7 +5904,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan database: DatabasePanel, uscounties: USCountiesPanel, autostart: () => , - awards: () => , + awards: () => , cat: CATPanel, rotator: RotatorPanel, winkeyer: WinkeyerPanel, diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx index 036f406..9e3f873 100644 --- a/frontend/src/lib/i18n.tsx +++ b/frontend/src/lib/i18n.tsx @@ -156,6 +156,7 @@ const en: Dict = { 'uscty.backfillRun': 'Fill missing counties', 'uscty.backfillDone': '{s} US QSOs scanned · {c} counties, {g} grids filled.', 'station.title': 'Station Control', 'station.rotator': 'Rotator', 'station.rotatorNoRead': 'No heading read', 'station.pattern': 'Pattern', 'station.bi': 'Bi', 'station.retract': 'Retract elements', 'station.moving': 'MOVING', 'station.elements': 'Elements (mm)', 'station.read': 'Read', 'station.readLengths': 'Read current element lengths from the controller', 'station.noLengths': 'Lengths unknown — click Read to fetch them from the controller.', 'station.element': 'Element', 'station.reflector': 'Reflector', 'station.driven': 'Driven', 'station.director': 'Dir', 'station.set': 'Set', 'station.elementsHint': 'Each press lengthens/shortens the element by 2 mm (like the physical console). Verify which element responds on your antenna.', 'station.setExactLen': 'Click to type the exact current length (fixes the baseline if the auto-read is off).', 'station.atMax': 'Controller refused — the element is likely at its maximum length for this band, so it can\'t extend further.', 'station.go': 'Go', 'station.stop': 'Stop', 'station.dragHint': 'Drag the grip handle on the left of a panel to move it. Pick a column count to lay them out in a grid.', 'station.dragMove': 'Drag to move this panel', 'station.colsAuto': 'Auto', 'station.addDevice': 'Add device', 'station.editDevice': 'Edit device', 'station.empty': 'No relay boards yet. Add a WebSwitch 1216H or a KMTronic 8-relay board to control your station power and accessories.', 'station.online': 'Online', 'station.offline': 'Offline', 'station.edit': 'Edit', 'station.delete': 'Delete', 'station.relay': 'Relay', 'station.on': 'ON', 'station.off': 'OFF', 'station.type': 'Device type', 'station.name': 'Name', 'station.host': 'Host / IP', 'station.hostHint': 'LAN IP for local use. To reach the board from OUTSIDE, put a full URL here — e.g. https://relay.yourdomain.com — pointing at a reverse proxy (Nginx Proxy Manager…) that fronts the board’s HTTP port.', 'station.user': 'Username', 'station.pass': 'Password', 'station.optional': 'optional', 'station.ftdiSerial': 'FTDI serial number', 'station.detect': 'Detect', 'station.ftdiHint': 'The Denkovi board is driven via FTDI bit-bang (not the COM port). Pick its serial (e.g. DAE0006K). Needs the FTDI D2XX driver installed.', 'station.channels': 'Relays', 'station.comPort': 'COM port', 'station.noPorts': 'No ports found', 'station.usbRelayHint': 'Cheap USB-serial relay boards (CH340/LCUS) using the A0 command protocol. If yours does not switch, tell me its model / command set.', 'station.labels': 'Relay labels', 'station.cancel': 'Cancel', 'station.save': 'Save', 'station.test': 'Test connection', 'station.testOk': 'Connected — {n} relays', 'station.testFail': 'Not connected', 'station.detectNone': 'No FTDI board found — check the cable and that the D2XX driver is installed.', 'station.detectFound': '{n} board(s) detected.', + 'awards.followHint': 'Awards shown in the Awards tab. Leave the right side empty to show them all.', 'awards.available': 'All awards', 'awards.followed': 'Followed', 'awards.search': 'Filter…', 'awards.addAll': 'Add all', 'awards.clear': 'Clear', 'awards.allTracked': 'All awards are followed.', 'awards.noneFollowed': 'Nothing followed yet — the Awards tab shows all.', 'sec.awards': 'Awards', 'sec.cat': 'CAT interface', 'sec.rotator': 'Rotator', 'sec.winkeyer': 'CW Keyer', 'sec.antenna': 'Ultrabeam / Steppir', 'sec.antgenius': 'Antenna Genius', 'sec.tunergenius': 'Tuner Genius', 'sec.pgxl': 'Amplifier', 'sec.flex': 'FlexRadio', 'sec.audio': 'Audio devices', // CW Keyer settings panel @@ -575,6 +576,7 @@ const fr: Dict = { 'uscty.backfillRun': 'Remplir les comtés manquants', 'uscty.backfillDone': '{s} QSO US analysés · {c} comtés, {g} locators remplis.', 'station.title': 'Contrôle station', 'station.rotator': 'Rotator', 'station.rotatorNoRead': 'Azimut non lu', 'station.pattern': 'Diagramme', 'station.bi': 'Bi', 'station.retract': 'Rétracter les éléments', 'station.moving': 'EN MOUVEMENT', 'station.elements': 'Éléments (mm)', 'station.read': 'Lire', 'station.readLengths': 'Lire les longueurs actuelles depuis le contrôleur', 'station.noLengths': 'Longueurs inconnues — clique sur Lire pour les récupérer depuis le contrôleur.', 'station.element': 'Élément', 'station.reflector': 'Réflecteur', 'station.driven': 'Radiateur', 'station.director': 'Dir', 'station.set': 'Régler', 'station.elementsHint': "Chaque appui allonge/raccourcit l'élément de 2 mm (comme le pupitre). Vérifie quel élément répond sur ton antenne.", 'station.setExactLen': "Clique pour taper la longueur actuelle exacte (recale la base si la lecture auto est fausse).", 'station.atMax': "Refusé par le contrôleur — l'élément est probablement en butée (longueur max pour cette bande), il ne peut plus s'allonger.", 'station.go': 'Aller', 'station.stop': 'Stop', 'station.dragHint': 'Glisse la poignée à gauche d un panneau pour le déplacer. Choisis un nombre de colonnes pour la disposition.', 'station.dragMove': 'Glisser pour déplacer ce panneau', 'station.colsAuto': 'Auto', 'station.addDevice': 'Ajouter un appareil', 'station.editDevice': "Modifier l'appareil", 'station.empty': "Aucune carte relais. Ajoute un WebSwitch 1216H ou une carte KMTronic 8 relais pour piloter l'alimentation et les accessoires de ta station.", 'station.online': 'En ligne', 'station.offline': 'Hors ligne', 'station.edit': 'Modifier', 'station.delete': 'Supprimer', 'station.relay': 'Relais', 'station.on': 'ON', 'station.off': 'OFF', 'station.type': "Type d'appareil", 'station.name': 'Nom', 'station.host': 'Hôte / IP', 'station.hostHint': "IP du LAN en local. Pour joindre la carte depuis L'EXTÉRIEUR, saisis une URL complète ici — ex. https://relais.tondomaine.com — pointant vers un reverse proxy (Nginx Proxy Manager…) qui expose le port HTTP de la carte.", 'station.user': "Nom d'utilisateur", 'station.pass': 'Mot de passe', 'station.optional': 'optionnel', 'station.ftdiSerial': 'Numéro de série FTDI', 'station.detect': 'Détecter', 'station.ftdiHint': "La carte Denkovi se pilote en FTDI bit-bang (pas via le port COM). Choisis son numéro de série (ex. DAE0006K). Nécessite le driver FTDI D2XX installé.", 'station.channels': 'Relais', 'station.comPort': 'Port COM', 'station.noPorts': 'Aucun port', 'station.usbRelayHint': "Cartes USB-série bon marché (CH340/LCUS) protocole A0. Si la tienne ne commute pas, donne-moi le modèle / jeu de commandes.", 'station.labels': 'Libellés des relais', 'station.cancel': 'Annuler', 'station.save': 'Enregistrer', 'station.test': 'Tester la connexion', 'station.testOk': 'Connecté — {n} relais', 'station.testFail': 'Non connecté', 'station.detectNone': 'Aucune carte FTDI trouvée — vérifie le câble et que le driver D2XX est installé.', 'station.detectFound': '{n} carte(s) détectée(s).', + 'awards.followHint': 'Diplômes affichés dans l’onglet Awards. Laisse la colonne de droite vide pour tous les afficher.', 'awards.available': 'Tous les diplômes', 'awards.followed': 'Suivis', 'awards.search': 'Filtrer…', 'awards.addAll': 'Tout ajouter', 'awards.clear': 'Vider', 'awards.allTracked': 'Tous les diplômes sont suivis.', 'awards.noneFollowed': 'Aucun pour l’instant — l’onglet Awards les montre tous.', 'sec.awards': 'Diplômes', 'sec.cat': 'Interface CAT', 'sec.rotator': 'Rotator', 'sec.winkeyer': 'Manipulateur CW', 'sec.antenna': 'Antenne motorisée', 'sec.antgenius': 'Antenna Genius', 'sec.tunergenius': 'Tuner Genius', 'sec.pgxl': 'Amplificateur', 'sec.flex': 'FlexRadio', 'sec.audio': 'Périphériques audio', // Panneau Manipulateur CW diff --git a/frontend/wailsjs/go/main/App.d.ts b/frontend/wailsjs/go/main/App.d.ts index 6db5187..09ac771 100644 --- a/frontend/wailsjs/go/main/App.d.ts +++ b/frontend/wailsjs/go/main/App.d.ts @@ -495,6 +495,8 @@ export function GetStationStatus():Promise>; export function GetTelemetryEnabled():Promise; +export function GetTrackedAwards():Promise>; + export function GetTunerGeniusSettings():Promise; export function GetTunerGeniusStatus():Promise; @@ -897,6 +899,8 @@ export function SaveStationDevices(arg1:Array):Promise export function SaveStationSettings(arg1:main.StationSettings):Promise; +export function SaveTrackedAwards(arg1:Array):Promise; + export function SaveTunerGeniusSettings(arg1:main.TunerGeniusSettings):Promise; export function SaveUDPIntegration(arg1:udp.Config):Promise; diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js index f7ed8ae..8a3465f 100644 --- a/frontend/wailsjs/go/main/App.js +++ b/frontend/wailsjs/go/main/App.js @@ -938,6 +938,10 @@ export function GetTelemetryEnabled() { return window['go']['main']['App']['GetTelemetryEnabled'](); } +export function GetTrackedAwards() { + return window['go']['main']['App']['GetTrackedAwards'](); +} + export function GetTunerGeniusSettings() { return window['go']['main']['App']['GetTunerGeniusSettings'](); } @@ -1742,6 +1746,10 @@ export function SaveStationSettings(arg1) { return window['go']['main']['App']['SaveStationSettings'](arg1); } +export function SaveTrackedAwards(arg1) { + return window['go']['main']['App']['SaveTrackedAwards'](arg1); +} + export function SaveTunerGeniusSettings(arg1) { return window['go']['main']['App']['SaveTunerGeniusSettings'](arg1); }