defmodule AprsmeWeb.MapLive.Components do
@moduledoc """
Reusable function components for the Map LiveView.
Extracted to improve maintainability and reduce the main LiveView module size.
"""
use AprsmeWeb, :html
attr :flash, :map, default: %{}
attr :slideover_open, :boolean, default: false
attr :rest, :global
def map_container(assigns) do
~H"""
"""
end
defp connection_indicator(assigns) do
~H"""
<%= case @connection_status do %>
<% "connected" -> %>
Connected to APRS-IS
<% "connecting" -> %>
Connecting to APRS-IS...
<% "disconnected" -> %>
Disconnected from APRS-IS
<% _ -> %>
Initializing...
<% end %>
"""
end
defp view_toggle(assigns) do
~H"""
"""
end
defp callsign_filter(assigns) do
~H"""
<%= if @tracked_callsign_latest_packet do %>
Last seen: {format_time_ago(@tracked_callsign_latest_packet.received_at)}
<% end %>
"""
end
defp packet_list(assigns) do
~H"""
<%= if @packets == [] do %>
No packets received yet...
<% else %>
<.packet_card packet={packet} />
<% end %>
"""
end
defp packet_card(assigns) do
~H"""
{@packet.sender}
<%= if @packet.ssid && @packet.ssid != "0" do %>
-{@packet.ssid}
<% end %>
<%= if @packet.has_position do %>
📍 {format_coordinates(@packet.lat, @packet.lon)}
<% end %>
<%= if @packet.comment do %>
{@packet.comment}
<% end %>
via {@packet.path || "direct"} • {format_time_ago(@packet.received_at)}
<%= if @packet.has_position do %>
<% end %>
"""
end
# Helper functions
defp format_time_ago(datetime) do
# Implement time ago formatting
case DateTime.diff(DateTime.utc_now(), datetime, :second) do
seconds when seconds < 60 -> "#{seconds}s ago"
seconds when seconds < 3600 -> "#{div(seconds, 60)}m ago"
seconds when seconds < 86_400 -> "#{div(seconds, 3600)}h ago"
seconds -> "#{div(seconds, 86_400)}d ago"
end
end
defp format_coordinates(lat, lon) when is_number(lat) and is_number(lon) do
"#{Float.round(lat * 1.0, 4)}, #{Float.round(lon * 1.0, 4)}"
end
defp format_coordinates(_, _), do: "Unknown location"
# Style component for better organization
def map_styles(assigns) do
~H"""
"""
end
end