diff --git a/client/public/robots.txt b/client/public/robots.txt
new file mode 100644
index 0000000..f6e6d1d
--- /dev/null
+++ b/client/public/robots.txt
@@ -0,0 +1,2 @@
+User-Agent: *
+Allow: /
diff --git a/client/src/components/Ship.vue b/client/src/components/Ship.vue
index 15983be..07da9f2 100644
--- a/client/src/components/Ship.vue
+++ b/client/src/components/Ship.vue
@@ -26,7 +26,8 @@ function cycleSpeed() {
const speed = computed(() => SPEED_UNITS[prefs.value.speed as keyof typeof SPEED_UNITS])
const name = computed(() => props.boat.shipname?.trim() || props.boat.callsign?.trim() || '-')
-const heading = computed(() => props.boat.heading ?? props.boat.course ?? 0)
+const heading = computed(() => props.boat.heading ?? props.boat.bearing)
+const course = computed(() => props.boat.cog ?? props.boat.course)
const speedVal = computed(() => speed.value.convert(props.boat.speed ?? 0))
const photoError = ref(false)
@@ -227,15 +228,15 @@ const compass = computed(() => {
Course
- {{ boat.course != null ? boat.course.toFixed(0) : '—' }}
- °
+ {{ course != null ? course.toFixed(0) : '—' }}
+ °
Heading
- {{ boat.heading != null ? boat.heading.toFixed(0) : '—' }}
- °
+ {{ heading != null ? heading.toFixed(0) : '—' }}
+ °
diff --git a/client/src/services/ais.ts b/client/src/services/ais.ts
index db718e3..f26203a 100644
--- a/client/src/services/ais.ts
+++ b/client/src/services/ais.ts
@@ -104,7 +104,7 @@ export class AISLayer {
image: new Icon({
src: buildBoatIcon(boat),
scale: 0.8,
- rotation: (boat.heading ?? boat.course ?? 0) * (Math.PI / 180),
+ rotation: (boat.heading ?? boat.bearing ?? boat.cog ?? boat.course ?? 0) * (Math.PI / 180),
anchor: [0.5, 0.5],
}),
}))
diff --git a/server/src/adsb.mjs b/server/src/adsb.mjs
index 7905a2a..8e37feb 100644
--- a/server/src/adsb.mjs
+++ b/server/src/adsb.mjs
@@ -346,18 +346,27 @@ export async function getADSBImage(icao) {
const data = await fetch(url,
{headers: {'User-Agent': 'Mozilla/5.0', 'Referer': 'https://duckduckgo.com/'}}
).then(resp => resp.json());
- return data?.results?.[0]?.image || null;
+ console.log(query, data.results)
+
+ // Sequentially try each image until we find a valid one
+ if (data?.results?.length) {
+ for (const result of data.results) {
+ if (!result.image) continue;
+ try {
+ const imgRes = await fetch(result.image);
+ if (imgRes.ok) return result.image;
+ } catch (e) {
+ continue; // Try next image
+ }
+ }
+ }
+ return null;
}
-
- const c = cfg();
- let aircraft = (await adsbCache).find(a => a.icao?.toLowerCase() === icao?.toLowerCase());
- if(!aircraft) aircraft = enrichAircraft({hex: icao});
- if(!aircraft) return null;
-
- const generic = duckduckgo(aircraft.model ? `${aircraft.manufacturer} ${aircraft.model}` : `${aircraft.aircraft} Aircraft`);
+ const aircraft = await this.get(icao);
+ const generic = duckduckgo(`${aircraft.type || aircraft.shape} Aircraft`);
const specific = await fetch(`https://api.planespotters.net/pub/photos/hex/${icao.toLowerCase()}`,
- {headers: {'User-Agent': `Personal ADSB Feeder + Dashboard (${c.EMAIL})`}}
+ {headers: {'User-Agent': `open-sight.net (zaktimson@gmail.com)`}}
).then(resp => resp.ok ? resp.json() : null);
let src;
diff --git a/server/src/ais.mjs b/server/src/ais.mjs
index 69d2578..f08f149 100644
--- a/server/src/ais.mjs
+++ b/server/src/ais.mjs
@@ -89,7 +89,6 @@ export async function getAIS() {
}
export async function getAISImage(mmsi) {
- console.log(`https://www.vesselfinder.com/vessels/details/${mmsi}`)
const res = await fetch(`https://www.vesselfinder.com/vessels/details/${mmsi}`, {
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36' }
})