Merge pull request #14 from aprsme/fix-trail-line-connections
Fix trail lines not connecting historical positions
This commit is contained in:
commit
8906e218dd
6 changed files with 96 additions and 10 deletions
11
.github/workflows/elixir.yaml
vendored
11
.github/workflows/elixir.yaml
vendored
|
|
@ -48,23 +48,18 @@ jobs:
|
|||
otp: ["27.3.4"]
|
||||
elixir: ["1.18.4"]
|
||||
steps:
|
||||
# Step: Setup Elixir + Erlang image as the base.
|
||||
- name: Set up Elixir
|
||||
# Step: Setup Elixir + Erlang + Gleam using erlef/setup-beam
|
||||
- name: Set up Elixir, Erlang, and Gleam
|
||||
uses: erlef/setup-beam@v1
|
||||
with:
|
||||
otp-version: ${{matrix.otp}}
|
||||
elixir-version: ${{matrix.elixir}}
|
||||
gleam-version: "1.5.1"
|
||||
|
||||
# Step: Check out the code.
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Step: Install Gleam
|
||||
- name: Set up Gleam
|
||||
uses: gleam-lang/setup-gleam@v1
|
||||
with:
|
||||
gleam-version: "1.5.1"
|
||||
|
||||
# Step: Install mix_gleam archive
|
||||
- name: Install mix_gleam
|
||||
run: mix archive.install hex mix_gleam 0.6.2 --force
|
||||
|
|
|
|||
|
|
@ -78,6 +78,24 @@ export class TrailManager {
|
|||
}
|
||||
}
|
||||
|
||||
setTrailDuration(durationHours: number) {
|
||||
this.trailDuration = durationHours * 60 * 60 * 1000; // Convert hours to milliseconds
|
||||
|
||||
// Clean up existing trails based on new duration
|
||||
const cutoffTime = Date.now() - this.trailDuration;
|
||||
|
||||
this.trails.forEach((trailState, baseCallsign) => {
|
||||
// Filter positions based on new duration (skip historical dots)
|
||||
trailState.positions = trailState.positions.filter((pos) => {
|
||||
const posTimestamp = typeof pos.timestamp === "string" ? new Date(pos.timestamp).getTime() : pos.timestamp;
|
||||
return posTimestamp >= cutoffTime;
|
||||
});
|
||||
|
||||
// Update trail visualization
|
||||
this.updateTrailVisualization(baseCallsign, trailState, true);
|
||||
});
|
||||
}
|
||||
|
||||
addPosition(
|
||||
markerId: string,
|
||||
lat: number,
|
||||
|
|
|
|||
|
|
@ -663,6 +663,13 @@ let MapAPRSMap = {
|
|||
}
|
||||
});
|
||||
|
||||
// Handle trail duration updates from LiveView
|
||||
self.handleEvent("update_trail_duration", (data: { duration_hours: number }) => {
|
||||
if (self.trailManager) {
|
||||
self.trailManager.setTrailDuration(data.duration_hours);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle new packets from LiveView
|
||||
self.handleEvent("new_packet", (data: MarkerData) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -34,8 +34,27 @@ export function parseTimestamp(timestamp: string | number | Date | undefined): n
|
|||
/**
|
||||
* Get trail ID from marker data
|
||||
*/
|
||||
export function getTrailId(data: { callsign_group?: string; callsign?: string; id: string }): string {
|
||||
return data.callsign_group || data.callsign || data.id;
|
||||
export function getTrailId(data: { callsign_group?: string; callsign?: string; id: string | number }): string {
|
||||
// Prioritize callsign_group and callsign over extracting from ID
|
||||
if (data.callsign_group) {
|
||||
return data.callsign_group;
|
||||
}
|
||||
|
||||
if (data.callsign) {
|
||||
return data.callsign;
|
||||
}
|
||||
|
||||
// For historical markers like "hist_CALLSIGN_123", extract the base callsign
|
||||
const id = String(data.id);
|
||||
if (id.startsWith("hist_")) {
|
||||
// Remove hist_ prefix and any trailing numeric index
|
||||
const withoutPrefix = id.replace(/^hist_/, "");
|
||||
// Remove trailing _digits pattern
|
||||
return withoutPrefix.replace(/_\d+$/, "");
|
||||
}
|
||||
|
||||
// For regular IDs, return as string
|
||||
return String(data.id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -360,6 +360,9 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
|
||||
socket = assign(socket, trail_duration: duration, packet_age_threshold: new_threshold)
|
||||
|
||||
# Update client-side TrailManager with new duration
|
||||
socket = push_event(socket, "update_trail_duration", %{duration_hours: hours})
|
||||
|
||||
# Trigger cleanup to remove packets that are now outside the new duration
|
||||
send(self(), :cleanup_old_packets)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,50 @@ describe('map_helpers', () => {
|
|||
};
|
||||
expect(getTrailId(data)).toBe('ID-1');
|
||||
});
|
||||
|
||||
test('extracts base callsign from historical ID format', () => {
|
||||
const data = {
|
||||
id: 'hist_MYCALL_123'
|
||||
};
|
||||
expect(getTrailId(data)).toBe('MYCALL');
|
||||
});
|
||||
|
||||
test('handles historical ID with complex callsign', () => {
|
||||
const data = {
|
||||
id: 'hist_KD8ABC-9_456'
|
||||
};
|
||||
expect(getTrailId(data)).toBe('KD8ABC-9');
|
||||
});
|
||||
|
||||
test('prioritizes callsign_group over historical ID extraction', () => {
|
||||
const data = {
|
||||
callsign_group: 'GROUP-1',
|
||||
id: 'hist_MYCALL_123'
|
||||
};
|
||||
expect(getTrailId(data)).toBe('GROUP-1');
|
||||
});
|
||||
|
||||
test('prioritizes callsign over historical ID extraction', () => {
|
||||
const data = {
|
||||
callsign: 'REALCALL',
|
||||
id: 'hist_MYCALL_123'
|
||||
};
|
||||
expect(getTrailId(data)).toBe('REALCALL');
|
||||
});
|
||||
|
||||
test('handles numeric ID', () => {
|
||||
const data = {
|
||||
id: 12345
|
||||
};
|
||||
expect(getTrailId(data)).toBe('12345');
|
||||
});
|
||||
|
||||
test('handles numeric historical ID', () => {
|
||||
const data = {
|
||||
id: 'hist_MYCALL_12345'
|
||||
};
|
||||
expect(getTrailId(data)).toBe('MYCALL');
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveMapState', () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue