Commit graph

33 commits

Author SHA1 Message Date
9aa836e462
refactor(map): share isValidCoordinate and unwrapLongitudes helpers
The coord-validation and antimeridian-unwrap logic added in the last
pass had been duplicated across map.ts, trail_manager.ts, and
info_map.ts. Move both into map_helpers.ts and import from there so
there is one authoritative implementation.
2026-04-21 09:17:52 -05:00
e90226dc21
fix(map): tighten edge cases in heatmap, info map, and trail color
- Heatmap: filter points with invalid coords or out-of-range intensity
  so malformed rows can't distort the layer.
- InfoMap: validate coords for range (not just NaN) and use an epsilon
  when comparing positions, so float noise doesn't cause needless
  re-renders or accept bogus data.
- TrailManager: getTrailCenter returns null for empty input instead of
  the ambiguous (0, 0) null-island; callers guard accordingly.
2026-04-20 18:05:31 -05:00
f777dcbb35
fix(map): stop trail spidering across antimeridian and close gaps
- Normalize longitude delta in trail_manager Haversine so wraps across
  180/-180 no longer compute a near-global distance and spuriously
  split the trail into short-segment-filtered pieces.
- Unwrap longitudes before building segments and drawing polylines in
  both the per-station TrailManager and the show_trail_line handler so
  a date-line crossing renders as a short hop instead of a line that
  wraps around the world.
- Raise maxHopDistance (10 -> 100 km) and drop minSegmentPoints (3 -> 2)
  so legitimate fast movers (aircraft, balloons) and short valid hops
  are drawn instead of being dropped.
- Unbind mousemove/mouseout handlers on a trail before removing it so
  queued events can't fire against discarded state.
- Fix self.isValidCoordinate TypeError in updateMarker (function is
  module-level, not on the hook) and add coord validation to
  show_trail_line.
- Null boundsTimer after clearTimeout for cleanup consistency.
2026-04-20 18:03:25 -05:00
Claude
a8051ce247
fix: code review refinements
- RegexCache: change ETS table from :public to :protected for consistency
  with other tables, preventing uncontrolled writes bypassing GenServer
- MobileChannel: ensure_float now returns nil instead of the original
  unparsed string on parse failure, so validate_bounds properly rejects it
- map.ts: remove dead commented-out localStorage code
- map.ts: use instanceof HTMLAnchorElement instead of unsafe type cast
  in popup navigation handler
- TrailManager: add destroyed flag to prevent stale RAF and debounce
  callbacks from firing after destroy, and clean up hover timer on destroy

https://claude.ai/code/session_01Ps7Zq3wiBur1RtRKN7JM6X
2026-03-27 16:18:27 -05:00
e048be18d1
fix: harden frontend hook lifecycle cleanup 2026-03-23 12:28:54 -05:00
22ccec7d06
Add hover tooltips to weather charts showing values at cursor position 2026-03-22 16:37:24 -05:00
ac42896271
fix: performance improvements and bug fixes across backend and frontend
Backend:
- Use indexed has_weather boolean for weather queries instead of 6 OR conditions
- Enable gzip compression for static assets
- Re-enable security headers (CSP, X-Frame-Options, X-Content-Type-Options)
- Supervise cleanup task via BroadcastTaskSupervisor instead of Task.start
- Relax IsSupervisor restart limits (5/60s) to survive transient network issues
- Remove dead code: empty cache invalidation block, commented-out logging

Frontend:
- Use callsignIndex for O(1) marker dedup instead of O(n) forEach scan
- Consolidate triple packet loop into single pass in new_packets handler
- Batch trail visualization updates via requestAnimationFrame
- Replace DOM querySelectorAll z-index scan with simple counter
- Only rebuild OMS markers when crossing clustering zoom threshold
- Clean up trail manager on hook destroy
- Remove dead commented-out localStorage code
2026-03-19 12:41:36 -05:00
b8d2095346
Fix UI issues: popup positioning, trail/cluster sync, CSS cleanup
- Remove CSS `bottom: 50px !important` on popups that pushed them too
  high above markers
- Hide trails when markers are clustered (zoom < 11) so trails don't
  point to invisible markers inside cluster bubbles
- Fix locate button overlap with zoom controls and keep it always
  light mode
- Remove duplicate slideover/toggle CSS from layout files (single
  source of truth in component)
- Remove dead CSS classes and standardize breakpoints to 1024px
- Add isDestroyed guards on async callbacks to prevent race conditions
- Escape callsigns in marker HTML to prevent XSS
- Replace Leaflet _container private API with getContainer()
- Clean up about page placeholder text
2026-02-20 09:46:45 -06:00
4558f694f4
Improve trail color distinctness and road contrast
Replace trail color palette with bold, high-saturation colors that avoid
yellows, oranges, and grays (common road colors on map tiles). Interleave
warm/cool tones so consecutive color assignments are maximally distinct.

Change color assignment to prefer globally unique colors first, falling
back to proximity-based deconfliction only when all 15 colors are in use.
2026-02-20 09:15:31 -06:00
2030a7c8a6
Fix trail hover showing wrong igate RF path
Use mousemove instead of mouseover so the RF path updates as the
cursor moves along the trail. Send the mouse position rather than
the nearest-position's coordinates so the path line anchors where
the user is actually hovering. Debounce and deduplicate events to
avoid flooding the server.
2026-02-19 18:20:49 -06:00
14fa16df6d
Fix RF path visualization for hovering over track points
parse_rf_path was filtering out all paths containing qA* constructs,
which is virtually every APRS-IS packet. The qA* element delimits the
RF path from the APRS-IS metadata — it should be split on, not
discarded. Now properly extracts digipeaters (before qA*) and the
igate (after qA*), while filtering APRS aliases like WIDE/RELAY/TRACE.

Also adds hover handlers to trail polylines so hovering anywhere on a
call's track shows the RF path, not just on the dot markers.
2026-02-19 15:41:32 -06:00
33799f3f33
Only show movement trails for stations that are actually moving
- Add minimum movement threshold (100m) to skip stationary stations
- Add max hop distance (10km) to break trails at igate-hopping artifacts
- Require 3+ points per segment to filter noise from 2-point jumps
2026-02-18 13:34:30 -06:00
ff06c13224
Fix JavaScript/TypeScript bugs in plotting and validation
- Fix rain chart: remove incorrect /10 division on rain_24h values
- Fix RF path: change dashArray null to undefined for type safety
- Clarify trail proximity threshold: use kilometers directly instead of degrees
- Improve coordinate validation: add isFinite() checks to prevent infinity values
- Add Sobelow skip annotations for existing security warnings
2026-02-09 11:16:04 -06:00
f94ac8097c
Add explicit NaN checks to trail coordinate validation
Add isNaN() checks in addition to isFinite() to catch NaN values before
they reach Leaflet's polyline renderer. This prevents 'can't access
property x, h is undefined' errors when invalid coordinates slip through.

Generated with Claude Code https://claude.com/claude-code
2025-10-25 12:08:31 -05:00
5e3f0bc5cf
fix coord bug 2025-10-19 09:06:58 -05:00
282948db98
fix: resolve Chart.js date adapter error for weather charts
- Combine Chart.js and date adapter into single bundle to ensure proper loading order
- Add validation to skip chart rendering when insufficient weather data (< 2 points)
- Update vendor loader to not load date adapter separately
- Prevents date adapter errors when weather stations have limited data
2025-08-09 17:20:27 -04:00
02d9879b79
Fix Chart.js loading issue in weather charts
- Added check for Chart.js availability before rendering
- Updated chart hooks to wait for Chart.js to load completely
- Prevents 'window.Chart is not a constructor' errors

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 16:35:24 -05:00
63a87f3be1
Fix Docker build JavaScript import errors with vendor bundle
Fixed the esbuild errors during Docker build where npm packages couldn't
be resolved. The issue was caused by node_modules being excluded from
the Docker build context in .dockerignore.

Implemented a proper vendor bundle strategy following Phoenix 1.7+ patterns:

- Created vendor.js that bundles all npm dependencies (Leaflet, Chart.js,
  topbar) and their CSS files into a single pre-built bundle
- Added vendor esbuild profile in config.exs with proper CSS/image loaders
- Updated mix.exs to build vendor bundle before app bundle in assets.deploy
- Modified JavaScript imports to use globally loaded libraries from vendor
  bundle instead of importing from node_modules
- Added vendor.js script tag to root.html.heex before app.js

This approach avoids Docker build failures by pre-bundling all vendor
dependencies, eliminating the need for node_modules during production builds.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 12:32:39 -05:00
9b034cd211
vendor all js 2025-07-21 11:09:14 -05:00
cf78298f46
Fix trail lines not connecting historical positions
When changing trail duration and historical data settings, historical positions
would show up on the map but trail lines wouldn't connect them. This was caused
by a mismatch between trail ID generation and callsign extraction.

## Changes

- Fix getTrailId() to properly extract base callsigns from historical marker IDs
- Add setTrailDuration() method to TrailManager for dynamic duration updates
- Add LiveView event to synchronize trail duration changes with client
- Add comprehensive tests for historical ID handling

## Problem
Historical markers have IDs like "hist_CALLSIGN_123" but getTrailId() was
returning the full ID while TrailManager.extractBaseCallsign() extracted just
"CALLSIGN", creating separate trails instead of connected ones.

## Solution
Updated getTrailId() to extract base callsigns from historical IDs using the
same logic as TrailManager, ensuring all positions from the same station use
the same trail ID and connect properly.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 08:31:16 -05:00
af4ab270e2
Replace any types with specific TypeScript types
- Add comprehensive type definitions for Leaflet plugins (heatmap, marker clustering, overlapping marker spiderfier)
- Create event payload interfaces for all LiveView events
- Add marker extension types for APRS-specific properties
- Define Chart.js dataset and configuration types
- Replace 74 instances of 'any' type across all TypeScript files
- Improve type safety for event handlers and state management
- Add proper typing for external library integrations

This refactoring enhances type safety throughout the codebase, making it easier to catch errors at compile time and improving IDE support for autocompletion and refactoring.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-17 17:55:27 -05:00
a31d38ec6a
different trail colors 2025-07-16 09:36:49 -05:00
1d1195ae87
js refactor 2025-07-16 09:23:33 -05:00
711d92ebb6
performance improvements 2025-07-08 10:03:52 -05:00
fc449ed5f9
en español 2025-07-05 15:51:39 -05:00
665c8cb867
weather chart cleanup 2025-07-05 13:39:26 -05:00
f1bc428086
deploy fix 2025-07-05 12:51:28 -05:00
8c06f1f8fa
more typescript and update weather charts in real time 2025-07-05 12:47:11 -05:00
43d4792760
map tweaks 2025-06-22 17:39:10 -05:00
24b8627fd0
callsign map working 2025-06-21 13:51:04 -05:00
cd011b9667
historical lines 2025-06-21 13:40:36 -05:00
8fdafcf01e
historical packets 2025-06-21 13:28:20 -05:00
08965143fb
tracks 2025-06-19 16:49:48 -05:00