diff --git a/app.go b/app.go index 3ad6bd8..79929f2 100644 --- a/app.go +++ b/app.go @@ -138,3 +138,25 @@ func (a *App) GetCharacterLocations() ([]CharacterLocation, error) { defer cancel() return a.ssi.GetCharacterLocations(ctx) } + +// SystemRegion holds system + region names from local DB +type SystemRegion struct { + System string `json:"system"` + Region string `json:"region"` +} + +// ListSystemsWithRegions returns all solar system names and their regions from the local SQLite DB +func (a *App) ListSystemsWithRegions() ([]SystemRegion, error) { + if a.ssi == nil || a.ssi.db == nil { + return nil, errors.New("db not initialised") + } + var rows []SystemRegion + // mapSolarSystems has regionID; mapRegions has regionName + q := `SELECT s.solarSystemName AS system, r.regionName AS region + FROM mapSolarSystems s + JOIN mapRegions r ON r.regionID = s.regionID` + if err := a.ssi.db.Raw(q).Scan(&rows).Error; err != nil { + return nil, err + } + return rows, nil +} diff --git a/frontend/src/components/RegionMap.tsx b/frontend/src/components/RegionMap.tsx index 18ce64d..ca2a209 100644 --- a/frontend/src/components/RegionMap.tsx +++ b/frontend/src/components/RegionMap.tsx @@ -98,6 +98,25 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho const [offRegionIndicators, setOffRegionIndicators] = useState([]); const [meanNeighborAngle, setMeanNeighborAngle] = useState>({}); const [charLocs, setCharLocs] = useState>([]); + const [focusUntil, setFocusUntil] = useState(null); + + // When focusSystem changes, set an expiry 20s in the future + useEffect(() => { + if (focusSystem) { + setFocusUntil(Date.now() + 20000); + } + }, [focusSystem]); + + // Timer to clear focus after expiry + useEffect(() => { + if (!focusUntil) return; + const id = setInterval(() => { + if (Date.now() > focusUntil) { + setFocusUntil(null); + } + }, 500); + return () => clearInterval(id); + }, [focusUntil]); useEffect(() => { const onKeyDown = async (e: KeyboardEvent) => { @@ -700,27 +719,35 @@ export const RegionMap = ({ regionName, focusSystem, isCompact = false, isWormho })} {/* Highlight focused system */} - {focusSystem && positions[focusSystem] && ( - - + + + + - + {focusSystem} + )} diff --git a/frontend/src/components/SearchDialog.tsx b/frontend/src/components/SearchDialog.tsx index dee537f..5a51e75 100644 --- a/frontend/src/components/SearchDialog.tsx +++ b/frontend/src/components/SearchDialog.tsx @@ -3,7 +3,6 @@ import { useNavigate } from 'react-router-dom'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { AhoCorasick } from '@/lib/aho'; -import pb from '@/lib/pocketbase'; interface SearchResult { system: string; @@ -11,26 +10,22 @@ interface SearchResult { } async function loadAllSystems(): Promise> { - // Fetch system names with regions from PocketBase, paginated and minimal fields - const perPage = 1000; - let page = 1; - const out: Array = []; - const seen = new Set(); - // loop pages until fewer than perPage items - while (true) { - const res = await pb.collection('regionview').getList(page, perPage, { fields: 'sysname,sysregion' }); - for (const item of res.items as any[]) { - const system: string = item.sysname; - const region: string = item.sysregion; - if (!seen.has(system)) { + // Fetch from Go (Wails): local SQLite DB via App.ListSystemsWithRegions + try { + const list = await (window as any)?.go?.main?.App?.ListSystemsWithRegions?.(); + if (Array.isArray(list)) { + const seen = new Set(); + const out: Array = []; + for (const item of list) { + const system = String(item.system); + if (seen.has(system)) continue; seen.add(system); - out.push({ system, region }); + out.push({ system, region: String(item.region) }); } + return out; } - if (res.items.length < perPage) break; - page += 1; - } - return out; + } catch (_) { /* noop */ } + return []; } export const SearchDialog: React.FC = () => { diff --git a/frontend/wails.json b/frontend/wails.json new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/frontend/wails.json @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/wailsjs/go/main/App.d.ts b/frontend/wailsjs/go/main/App.d.ts index 84cc0c6..27735f7 100644 --- a/frontend/wailsjs/go/main/App.d.ts +++ b/frontend/wailsjs/go/main/App.d.ts @@ -14,6 +14,8 @@ export function Greet(arg1:string):Promise; export function ListCharacters():Promise>; +export function ListSystemsWithRegions():Promise>; + export function PostRouteForAllByNames(arg1:string,arg2:Array):Promise; export function SetDestinationForAll(arg1:string,arg2:boolean,arg3:boolean):Promise; diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js index 6f49768..fa94113 100644 --- a/frontend/wailsjs/go/main/App.js +++ b/frontend/wailsjs/go/main/App.js @@ -26,6 +26,10 @@ export function ListCharacters() { return window['go']['main']['App']['ListCharacters'](); } +export function ListSystemsWithRegions() { + return window['go']['main']['App']['ListSystemsWithRegions'](); +} + export function PostRouteForAllByNames(arg1, arg2) { return window['go']['main']['App']['PostRouteForAllByNames'](arg1, arg2); } diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts index b3073b4..b951b4e 100644 --- a/frontend/wailsjs/go/models.ts +++ b/frontend/wailsjs/go/models.ts @@ -53,6 +53,20 @@ export namespace main { return a; } } + export class SystemRegion { + system: string; + region: string; + + static createFrom(source: any = {}) { + return new SystemRegion(source); + } + + constructor(source: any = {}) { + if ('string' === typeof source) source = JSON.parse(source); + this.system = source["system"]; + this.region = source["region"]; + } + } }