add oban tables
This commit is contained in:
parent
7a57739ed7
commit
f9fa765e32
3 changed files with 16 additions and 246 deletions
|
|
@ -73,26 +73,6 @@ Hooks.APRSMap = {
|
|||
|
||||
console.log("Map initialized");
|
||||
|
||||
// Handle geolocation requests from server
|
||||
this.handleEvent("request_geolocation", () => {
|
||||
if ("geolocation" in navigator) {
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(position) => {
|
||||
const { latitude, longitude } = position.coords;
|
||||
console.log("User location:", latitude, longitude);
|
||||
map.setView([latitude, longitude], 12);
|
||||
// Notify server of new location
|
||||
this.pushEvent("set_location", { lat: latitude, lng: longitude });
|
||||
},
|
||||
(error) => {
|
||||
console.warn("Geolocation error:", error.message);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
console.warn("Geolocation not available in this browser");
|
||||
}
|
||||
});
|
||||
|
||||
// Add OpenStreetMap tile layer
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution:
|
||||
|
|
@ -149,12 +129,10 @@ Hooks.APRSMap = {
|
|||
// Store markers to avoid duplicates
|
||||
this.markers = new Map();
|
||||
this.historicalMarkers = new Map();
|
||||
this.packetCount = 0;
|
||||
|
||||
// Store map instance and initialize state
|
||||
this.map = map;
|
||||
this.mapReady = false;
|
||||
this.userLocationMarker = null;
|
||||
|
||||
// Send initial bounds to server
|
||||
this.sendBoundsToServer();
|
||||
|
|
@ -211,23 +189,6 @@ Hooks.APRSMap = {
|
|||
console.log("Map view updated after delay");
|
||||
console.log("New map center:", this.map.getCenter());
|
||||
console.log("New map zoom:", this.map.getZoom());
|
||||
|
||||
// Add a marker at the user's location
|
||||
if (this.userLocationMarker) {
|
||||
this.map.removeLayer(this.userLocationMarker);
|
||||
}
|
||||
|
||||
this.userLocationMarker = L.marker([lat, lng], {
|
||||
icon: L.divIcon({
|
||||
html: '<div style="background-color: #4299e1; width: 12px; height: 12px; border-radius: 50%; border: 2px solid white; box-shadow: 0 1px 3px rgba(0,0,0,0.4);"></div>',
|
||||
className: "user-location-marker",
|
||||
iconSize: [16, 16],
|
||||
iconAnchor: [8, 8],
|
||||
}),
|
||||
})
|
||||
.addTo(this.map)
|
||||
.bindPopup("Your location")
|
||||
.openPopup();
|
||||
}, 300);
|
||||
} else {
|
||||
console.error("Invalid coordinates in zoom_to_location event:", data);
|
||||
|
|
@ -312,11 +273,6 @@ Hooks.APRSMap = {
|
|||
}
|
||||
this.markers.clear();
|
||||
this.historicalMarkers.clear();
|
||||
this.packetCount = 0;
|
||||
const counterElement = document.getElementById("packet-count");
|
||||
if (counterElement) {
|
||||
counterElement.textContent = this.packetCount;
|
||||
}
|
||||
},
|
||||
|
||||
refreshMarkers() {
|
||||
|
|
@ -345,13 +301,6 @@ Hooks.APRSMap = {
|
|||
this.markers.delete(callsign);
|
||||
}
|
||||
});
|
||||
|
||||
// Update counter
|
||||
this.packetCount = this.markers.size;
|
||||
const counterElement = document.getElementById("packet-count");
|
||||
if (counterElement) {
|
||||
counterElement.textContent = this.packetCount;
|
||||
}
|
||||
},
|
||||
|
||||
clearHistoricalMarkers() {
|
||||
|
|
@ -370,10 +319,7 @@ Hooks.APRSMap = {
|
|||
},
|
||||
|
||||
removeMarkersOutsideBounds(bounds) {
|
||||
// Let LiveView handle the packet count
|
||||
// The cluster handles marker visibility automatically
|
||||
const visibleCount = this.markers.size;
|
||||
this.pushEvent("update_packet_count", { count: visibleCount });
|
||||
},
|
||||
|
||||
addPacketMarker(packet, isHistorical = false) {
|
||||
|
|
@ -473,15 +419,6 @@ Hooks.APRSMap = {
|
|||
|
||||
// Store the marker
|
||||
markerCollection.set(markerId, marker);
|
||||
|
||||
// Update packet counter (only for live packets)
|
||||
if (!isHistorical) {
|
||||
this.packetCount++;
|
||||
const counterElement = document.getElementById("packet-count");
|
||||
if (counterElement) {
|
||||
counterElement.textContent = this.packetCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ defmodule AprsWeb.MapLive.Index do
|
|||
socket =
|
||||
assign(socket,
|
||||
packets: [],
|
||||
packet_count: 0,
|
||||
page_title: "APRS Map",
|
||||
# Track visible packets by callsign
|
||||
visible_packets: %{},
|
||||
|
|
@ -117,8 +116,6 @@ defmodule AprsWeb.MapLive.Index do
|
|||
end)
|
||||
|> Map.new()
|
||||
|
||||
packet_count = map_size(visible_packets)
|
||||
|
||||
# If replay is not active, update the replay packets based on the new bounds
|
||||
socket =
|
||||
if socket.assigns.replay_active do
|
||||
|
|
@ -138,13 +135,7 @@ defmodule AprsWeb.MapLive.Index do
|
|||
socket
|
||||
end
|
||||
|
||||
{:noreply, assign(socket, map_bounds: map_bounds, visible_packets: visible_packets, packet_count: packet_count)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("update_packet_count", %{"count" => count}, socket) do
|
||||
# Update packet count from client after markers are removed
|
||||
{:noreply, assign(socket, packet_count: count)}
|
||||
{:noreply, assign(socket, map_bounds: map_bounds, visible_packets: visible_packets)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
@ -337,13 +328,12 @@ defmodule AprsWeb.MapLive.Index do
|
|||
|
||||
# Update visible packets tracking
|
||||
visible_packets = Map.put(socket.assigns.visible_packets, callsign_key, sanitized_packet)
|
||||
packet_count = map_size(visible_packets)
|
||||
|
||||
# Push the packet to the client-side JavaScript
|
||||
socket =
|
||||
socket
|
||||
|> push_event("new_packet", packet_data)
|
||||
|> assign(visible_packets: visible_packets, packet_count: packet_count)
|
||||
|> assign(visible_packets: visible_packets)
|
||||
|
||||
{:noreply, socket}
|
||||
else
|
||||
|
|
@ -458,18 +448,6 @@ defmodule AprsWeb.MapLive.Index do
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
.map-overlay {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 10px 15px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
||||
z-index: 1000;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.locate-button {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
|
|
@ -486,112 +464,6 @@ defmodule AprsWeb.MapLive.Index do
|
|||
background: #f4f4f4;
|
||||
}
|
||||
|
||||
.packet-counter {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.replay-badge {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
padding: 2px 6px;
|
||||
border-radius: 10px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% { opacity: 0.7; }
|
||||
50% { opacity: 1; }
|
||||
100% { opacity: 0.7; }
|
||||
}
|
||||
|
||||
.replay-controls {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.control-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.replay-controls button {
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.btn-action {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: #e74c3c;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: #7f8c8d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.speed-control {
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.speed-control input {
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.replay-progress {
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
height: 6px;
|
||||
background-color: #eee;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background-color: #3498db;
|
||||
transition: width 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 10px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.aprs-marker {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
|
|
@ -613,55 +485,6 @@ defmodule AprsWeb.MapLive.Index do
|
|||
>
|
||||
</div>
|
||||
|
||||
<div class="map-overlay">
|
||||
<div class="packet-counter">
|
||||
<span id="packet-count">{@packet_count}</span>
|
||||
packets in view
|
||||
<%= if @replay_active do %>
|
||||
<div class="replay-status">
|
||||
<span class="replay-badge">Replaying historical packets</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="replay-controls">
|
||||
<%= if @replay_active do %>
|
||||
<div class="control-buttons">
|
||||
<button phx-click="toggle_replay" class="btn-action">
|
||||
<span class="icon">⟳</span> Restart
|
||||
</button>
|
||||
<button phx-click="pause_replay" class="btn-secondary">
|
||||
<span class="icon">{if @replay_paused, do: "▶", else: "⏸"}</span>
|
||||
{if @replay_paused, do: "Resume", else: "Pause"}
|
||||
</button>
|
||||
</div>
|
||||
<div class="speed-control">
|
||||
<label>Speed: {@replay_speed}x</label>
|
||||
<input
|
||||
type="range"
|
||||
min="1"
|
||||
max="20"
|
||||
step="1"
|
||||
value={@replay_speed}
|
||||
phx-change="adjust_replay_speed"
|
||||
name="speed"
|
||||
/>
|
||||
</div>
|
||||
<div class="replay-progress">
|
||||
<div class="progress-bar">
|
||||
<div
|
||||
class="progress-fill"
|
||||
style={"width: #{if length(@replay_packets) > 0, do: @replay_index * 100 / length(@replay_packets), else: 0}%"}
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-text">
|
||||
{@replay_index} of {length(@replay_packets)} packets
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="locate-button" phx-click="locate_me" title="Find my location">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -695,16 +518,12 @@ defmodule AprsWeb.MapLive.Index do
|
|||
end)
|
||||
|> Map.new()
|
||||
|
||||
# Get updated packet count
|
||||
packet_count = map_size(visible_packets)
|
||||
|
||||
# Push event to remove old markers from the map
|
||||
socket =
|
||||
socket
|
||||
|> push_event("refresh_markers", %{})
|
||||
|> assign(
|
||||
visible_packets: visible_packets,
|
||||
packet_count: packet_count,
|
||||
packet_age_threshold: one_hour_ago
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
defmodule Aprs.Repo.Migrations.UpgradeObanToLatest do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
# First, drop the existing migration and start fresh
|
||||
# This ensures we get all the latest schema changes
|
||||
Oban.Migrations.up()
|
||||
end
|
||||
|
||||
def down do
|
||||
# This will rollback to the previous state
|
||||
Oban.Migrations.down()
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue