updat edeps
This commit is contained in:
parent
281aef095c
commit
77d2a6ca30
15 changed files with 600 additions and 82 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -61,3 +61,13 @@ gleam@@compile.erl
|
|||
/.expert
|
||||
.envrc
|
||||
.worktrees/
|
||||
|
||||
# Nix development environment state
|
||||
.nix-mix/
|
||||
.nix-hex/
|
||||
.nix-postgres/
|
||||
.nix-postgres-version
|
||||
.nix-services-started
|
||||
.direnv/
|
||||
# Generated by pre-commit-hooks.nix (symlink into /nix/store)
|
||||
.pre-commit-config.yaml
|
||||
|
|
|
|||
124
flake.lock
generated
Normal file
124
flake.lock
generated
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
"owner": "NixOS",
|
||||
"repo": "flake-compat",
|
||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769996383,
|
||||
"narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "57928607ea566b5db3ad13af0e57e921e6b12381",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"pre-commit-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1784120854,
|
||||
"narHash": "sha256-KesHgItiZPgGX740axSiQLcIQ8D24MDqNpkKYWIek8k=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "753cc8a3a87467296ddd1fa93f0cc3e81120ee46",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"pre-commit-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769939035,
|
||||
"narHash": "sha256-Fok2AmefgVA0+eprw2NDwqKkPGEI5wvR+twiZagBvrg=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "a8ca480175326551d6c4121498316261cbb5b260",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"pre-commit-hooks": "pre-commit-hooks",
|
||||
"systems": "systems"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
73
flake.nix
Normal file
73
flake.nix
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
description = "aprs.me - Phoenix LiveView APRS packet mapping platform";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
|
||||
flake-parts = {
|
||||
url = "github:hercules-ci/flake-parts";
|
||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
systems.url = "github:nix-systems/default";
|
||||
|
||||
pre-commit-hooks = {
|
||||
url = "github:cachix/pre-commit-hooks.nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs@{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-parts,
|
||||
systems,
|
||||
pre-commit-hooks,
|
||||
}:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
# nixpkgs 26.11 dropped x86_64-darwin support
|
||||
systems = builtins.filter (s: s != "x86_64-darwin") (import systems);
|
||||
|
||||
perSystem =
|
||||
{
|
||||
config,
|
||||
self',
|
||||
inputs',
|
||||
pkgs,
|
||||
system,
|
||||
...
|
||||
}:
|
||||
{
|
||||
_module.args.pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
# Pin specific Elixir and Erlang versions to match .tool-versions
|
||||
# Elixir 1.20.2-otp-29, Erlang 29.0.1
|
||||
(final: prev: {
|
||||
# Use Erlang 29 — no top-level erlang_29 yet, use beam.interpreters
|
||||
erlang = prev.beam.interpreters.erlang_29;
|
||||
|
||||
# Use Elixir 1.20 with Erlang 29 (1.20.2-otp-29)
|
||||
elixir = prev.beam.packages.erlang_29.elixir_1_20;
|
||||
|
||||
# Ensure beam packages use our pinned versions
|
||||
beamPackages = prev.beam.packages.erlang_29.extend (
|
||||
self: super: {
|
||||
elixir = super.elixir_1_20;
|
||||
}
|
||||
);
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
# Development shell with PostgreSQL (PostGIS), LSPs, formatters
|
||||
devShells.default = pkgs.callPackage ./nix/shell.nix {
|
||||
pre-commit-hooks = inputs.pre-commit-hooks.lib.${system};
|
||||
};
|
||||
|
||||
# Nix formatter for flake files
|
||||
formatter = pkgs.nixfmt;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -35,15 +35,15 @@
|
|||
{assigns[:page_title] || "Aprs"}
|
||||
</.live_title>
|
||||
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
|
||||
|
||||
<!-- Minimal vendor CSS -->
|
||||
|
||||
<!-- Minimal vendor CSS -->
|
||||
<link phx-track-static rel="stylesheet" href={~p"/assets/vendor/css/minimal-bundle.css"} />
|
||||
|
||||
<!-- Core utilities - always loaded -->
|
||||
|
||||
<!-- Core utilities - always loaded -->
|
||||
<script phx-track-static src={~p"/assets/vendor/js/core-bundle.js"}>
|
||||
</script>
|
||||
|
||||
<!-- Conditional loading based on page type -->
|
||||
|
||||
<!-- Conditional loading based on page type -->
|
||||
<script>
|
||||
window.VendorLoader = {
|
||||
mapBundleUrl: '/assets/vendor/js/map-bundle.js',
|
||||
|
|
@ -72,12 +72,12 @@
|
|||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- App scripts -->
|
||||
|
||||
<!-- App scripts -->
|
||||
<script phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
|
||||
</script>
|
||||
|
||||
<!-- Privacy-friendly analytics by Plausible -->
|
||||
|
||||
<!-- Privacy-friendly analytics by Plausible -->
|
||||
<script async src="https://a.w5isp.com/js/pa-7BkaTcdFcxr5y-7yhqhlJ.js">
|
||||
</script>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -363,8 +363,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
RESTful JSON API for accessing APRS packet data and station information.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- API Overview -->
|
||||
|
||||
<!-- API Overview -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10 mb-8">
|
||||
<div class="px-6 py-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-900 dark:text-white">Overview</h2>
|
||||
|
|
@ -415,8 +415,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- API Endpoints -->
|
||||
|
||||
<!-- API Endpoints -->
|
||||
<div class="space-y-8">
|
||||
<!-- Callsign Endpoint -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
|
|
@ -499,8 +499,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Weather Nearby Endpoint -->
|
||||
|
||||
<!-- Weather Nearby Endpoint -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<div class="px-6 py-8">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
|
|
@ -627,8 +627,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Response Fields Documentation -->
|
||||
|
||||
<!-- Response Fields Documentation -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<div class="px-6 py-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Response Fields</h2>
|
||||
|
|
@ -726,8 +726,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- HTTP Status Codes -->
|
||||
|
||||
<!-- HTTP Status Codes -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<div class="px-6 py-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">HTTP Status Codes</h2>
|
||||
|
|
@ -789,8 +789,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Future Endpoints -->
|
||||
|
||||
<!-- Future Endpoints -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<div class="px-6 py-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Planned Endpoints</h2>
|
||||
|
|
@ -843,8 +843,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Interactive API Testing -->
|
||||
|
||||
<!-- Interactive API Testing -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<div class="px-6 py-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Test the API</h2>
|
||||
|
|
@ -897,8 +897,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Error Display -->
|
||||
|
||||
<!-- Error Display -->
|
||||
<%= if @error do %>
|
||||
<div class="rounded-md bg-red-50 p-4 dark:bg-red-500/10 mt-4 max-w-md">
|
||||
<div class="flex">
|
||||
|
|
@ -920,8 +920,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Results Display -->
|
||||
|
||||
<!-- Results Display -->
|
||||
<%= if @api_result do %>
|
||||
<div class="mt-4">
|
||||
<h4 class="text-lg font-medium mb-2">API Response</h4>
|
||||
|
|
@ -946,8 +946,8 @@ defmodule AprsmeWeb.ApiDocsLive do
|
|||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact and Support -->
|
||||
|
||||
<!-- Contact and Support -->
|
||||
<div class="bg-white shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<div class="px-6 py-8">
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Support</h2>
|
||||
|
|
|
|||
|
|
@ -185,8 +185,8 @@
|
|||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Map showing station location -->
|
||||
|
||||
<!-- Map showing station location -->
|
||||
<%= if @packet.lat && @packet.lon do %>
|
||||
<div class="bg-white shadow-xs sm:rounded-lg ring-1 ring-gray-950/5 dark:bg-gray-800/50 dark:shadow-none dark:ring-white/10 h-full">
|
||||
<% {symbol_table, symbol_code} = AprsmeWeb.AprsSymbol.extract_from_packet(@packet) %>
|
||||
|
|
@ -202,8 +202,8 @@
|
|||
/>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Row for Device Information and Other SSIDs -->
|
||||
|
||||
<!-- Row for Device Information and Other SSIDs -->
|
||||
<div class="lg:col-span-2 grid grid-cols-1 gap-4 lg:grid-cols-2">
|
||||
<!-- Device information -->
|
||||
<div class="bg-white shadow-xs sm:rounded-lg ring-1 ring-gray-950/5 dark:bg-gray-800/50 dark:shadow-none dark:ring-white/10">
|
||||
|
|
@ -293,8 +293,8 @@
|
|||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Other SSIDs -->
|
||||
|
||||
<!-- Other SSIDs -->
|
||||
<%= if length(@other_ssids) > 0 do %>
|
||||
<div class="bg-white shadow-xs sm:rounded-lg ring-1 ring-gray-950/5 dark:bg-gray-800/50 dark:shadow-none dark:ring-white/10">
|
||||
<div class="px-6 py-6">
|
||||
|
|
@ -407,8 +407,8 @@
|
|||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Neighboring stations -->
|
||||
|
||||
<!-- Neighboring stations -->
|
||||
<div class="bg-white shadow-xs sm:rounded-lg ring-1 ring-gray-950/5 dark:bg-gray-800/50 dark:shadow-none dark:ring-white/10">
|
||||
<div class="px-6 py-6">
|
||||
<div class="flex items-center mb-3">
|
||||
|
|
@ -502,8 +502,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stations that heard this callsign on RF -->
|
||||
|
||||
<!-- Stations that heard this callsign on RF -->
|
||||
<%= if length(@heard_by_stations) > 0 do %>
|
||||
<div class="bg-white shadow-xs sm:rounded-lg ring-1 ring-gray-950/5 dark:bg-gray-800/50 dark:shadow-none dark:ring-white/10 mt-6">
|
||||
<div class="px-6 py-6">
|
||||
|
|
@ -607,8 +607,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Stations heard directly by this callsign -->
|
||||
|
||||
<!-- Stations heard directly by this callsign -->
|
||||
<%= if length(@stations_heard_by) > 0 do %>
|
||||
<div class="bg-white shadow-xs sm:rounded-lg ring-1 ring-gray-950/5 dark:bg-gray-800/50 dark:shadow-none dark:ring-white/10 mt-6">
|
||||
<div class="px-6 py-6">
|
||||
|
|
|
|||
|
|
@ -1457,8 +1457,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
{gettext("Real-time APRS packet tracking")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
|
||||
<!-- Content -->
|
||||
<div class="relative flex-1 overflow-y-auto bg-white px-5 py-5 dark:bg-gray-800 dark:after:absolute dark:after:inset-y-0 dark:after:left-0 dark:after:w-px dark:after:bg-white/10">
|
||||
<div class="space-y-5">
|
||||
<!-- Callsign Search -->
|
||||
|
|
@ -1507,8 +1507,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
<% end %>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Other SSIDs -->
|
||||
|
||||
<!-- Other SSIDs -->
|
||||
<%= if @tracked_callsign != "" and @other_ssids != [] do %>
|
||||
<div class="rounded-lg bg-gray-50 p-4 ring-1 ring-gray-950/5 dark:bg-gray-900/50 dark:ring-white/10">
|
||||
<label class="mb-3 flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">
|
||||
|
|
@ -1558,8 +1558,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Trail Duration -->
|
||||
|
||||
<!-- Trail Duration -->
|
||||
<div class="rounded-lg bg-gray-50 p-4 ring-1 ring-gray-950/5 dark:bg-gray-900/50 dark:ring-white/10">
|
||||
<label class="mb-3 flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">
|
||||
<svg class="h-3.5 w-3.5 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -1572,7 +1572,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
</svg>
|
||||
{gettext("Trail Duration")}
|
||||
</label>
|
||||
<form phx-change="update_trail_duration">
|
||||
<form id="trail-duration-form" phx-change="update_trail_duration">
|
||||
<select
|
||||
name="trail_duration"
|
||||
class="block w-full rounded-md bg-white px-3 py-2 text-sm text-gray-900 shadow-xs outline-1 -outline-offset-1 outline-gray-300 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 dark:bg-gray-800 dark:text-white dark:outline-white/10 dark:focus:outline-indigo-500"
|
||||
|
|
@ -1598,8 +1598,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Historical Data -->
|
||||
|
||||
<!-- Historical Data -->
|
||||
<div class="rounded-lg bg-gray-50 p-4 ring-1 ring-gray-950/5 dark:bg-gray-900/50 dark:ring-white/10">
|
||||
<label class="mb-3 flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">
|
||||
<svg class="h-3.5 w-3.5 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -1612,7 +1612,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
</svg>
|
||||
{gettext("Historical Data")}
|
||||
</label>
|
||||
<form phx-change="update_historical_hours">
|
||||
<form id="historical-hours-form" phx-change="update_historical_hours">
|
||||
<select
|
||||
name="historical_hours"
|
||||
class="block w-full rounded-md bg-white px-3 py-2 text-sm text-gray-900 shadow-xs outline-1 -outline-offset-1 outline-gray-300 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 dark:bg-gray-800 dark:text-white dark:outline-white/10 dark:focus:outline-indigo-500"
|
||||
|
|
@ -1635,8 +1635,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Navigation -->
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-white/10">
|
||||
<label class="mb-3 flex items-center gap-2 text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400">
|
||||
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
|
|
@ -1658,8 +1658,8 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
/>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Status Footer -->
|
||||
|
||||
<!-- Status Footer -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-white/10">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -70,8 +70,8 @@ defmodule AprsmeWeb.StatusLive.ConnectionCardComponent do
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Packet Statistics -->
|
||||
|
||||
<!-- Packet Statistics -->
|
||||
<div class="border-t border-gray-200 dark:border-white/10 my-4"></div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-3">Packet Statistics</h3>
|
||||
|
|
|
|||
|
|
@ -140,8 +140,8 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- APRS-IS Connection Status -->
|
||||
|
||||
<!-- APRS-IS Connection Status -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">{gettext("APRS-IS Connection")}</h2>
|
||||
<div class="rounded-lg bg-gray-50 p-6 dark:bg-gray-700/50">
|
||||
|
|
@ -206,8 +206,8 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Packet Statistics -->
|
||||
|
||||
<!-- Packet Statistics -->
|
||||
<div class="border-t border-gray-200 dark:border-white/10 my-4"></div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-3 text-gray-900 dark:text-white">{gettext("Packet Statistics")}</h3>
|
||||
|
|
@ -285,8 +285,8 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Health Score -->
|
||||
|
||||
<!-- Health Score -->
|
||||
<div class="border-t border-gray-200 dark:border-white/10 my-4"></div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm font-medium text-gray-500 dark:text-gray-400">{gettext("Connection Health:")}</span>
|
||||
|
|
@ -317,8 +317,8 @@ defmodule AprsmeWeb.StatusLive.Index do
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cluster Information (if available) -->
|
||||
|
||||
<!-- Cluster Information (if available) -->
|
||||
<%= if Map.has_key?(@aprs_status, :cluster_info) do %>
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4 text-gray-900 dark:text-white">{gettext("Cluster Status")}</h2>
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ defmodule AprsmeWeb.UserSettingsLive do
|
|||
</div>
|
||||
</.simple_form>
|
||||
</div>
|
||||
|
||||
<!-- Change Callsign Section -->
|
||||
|
||||
<!-- Change Callsign Section -->
|
||||
<div class="bg-white px-6 py-8 shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-6 dark:text-white">Change Callsign</h2>
|
||||
|
||||
|
|
@ -179,8 +179,8 @@ defmodule AprsmeWeb.UserSettingsLive do
|
|||
</div>
|
||||
</.simple_form>
|
||||
</div>
|
||||
|
||||
<!-- Change Password Section -->
|
||||
|
||||
<!-- Change Password Section -->
|
||||
<div class="bg-white px-6 py-8 shadow-sm sm:rounded-lg dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10">
|
||||
<h2 class="text-xl font-semibold text-gray-900 mb-6 dark:text-white">Change Password</h2>
|
||||
|
||||
|
|
|
|||
4
mix.exs
4
mix.exs
|
|
@ -94,7 +94,7 @@ defmodule Aprsme.MixProject do
|
|||
{:phoenix_html, "~> 4.3.0"},
|
||||
{:phoenix_live_dashboard, "~> 0.8"},
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
{:phoenix_live_view, "~> 1.1.26"},
|
||||
{:phoenix_live_view, "~> 1.2"},
|
||||
{:postgrex, ">= 0.0.0"},
|
||||
{:swoosh, "~> 1.23"},
|
||||
{:telemetry_metrics, "~> 1.0"},
|
||||
|
|
@ -102,7 +102,7 @@ defmodule Aprsme.MixProject do
|
|||
{:prom_ex, "~> 1.12"},
|
||||
aprs_dep(),
|
||||
{:esbuild, "~> 0.10", runtime: Mix.env() == :dev},
|
||||
{:tailwind, "~> 0.4.0", runtime: Mix.env() == :dev},
|
||||
{:tailwind, "~> 0.5", runtime: Mix.env() == :dev},
|
||||
{:bandit, "~> 1.5"},
|
||||
{:req, "~> 0.5"},
|
||||
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
|
||||
|
|
|
|||
18
mix.lock
18
mix.lock
|
|
@ -3,7 +3,7 @@
|
|||
"bandit": {:hex, :bandit, "1.12.0", "6c5214daa2469644ac4ab0113b98abc24f75e348378e6a974c6343b3e5da22ef", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.18", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.5", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "45dac82dc86f45cf4a196dee9cc5a8b791d9c9469d996055f055e6ee36c66e20"},
|
||||
"bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"},
|
||||
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
||||
"castore": {:hex, :castore, "1.0.19", "6903cabdfd9d1af46454126e7c8385186659dd33ecfb74a885cae52221ad6109", [:mix], [], "hexpm", "3669e6cab13f54c2df26b3e6833745d647f35b6e30d8ddd5975df0d5c842ca98"},
|
||||
"castore": {:hex, :castore, "1.0.20", "455e48f7115eca98c9f2b0e7a152b5a2e8f2a8a4f964c96e95bd31645ee5fa59", [:mix], [], "hexpm", "940eafbfd8b14bee649f083bc11b3b54ec555b54c3e4ea8213351ff6fee39c10"},
|
||||
"cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"},
|
||||
"circular_buffer": {:hex, :circular_buffer, "1.0.1", "01f0e3d5fe945080692cf6521c0988e9dbb5dc312831cefe77e5b63a4e658160", [:mix], [], "hexpm", "7d4ece3137d49c1f8dd0b3e0aa7c484f4d83a0be5d4b516c282085c1d5f2d7b9"},
|
||||
"comeonin": {:hex, :comeonin, "5.5.1", "5113e5f3800799787de08a6e0db307133850e635d34e9fab23c70b6501669510", [:mix], [], "hexpm", "65aac8f19938145377cee73973f192c5645873dcf550a8a6b18187d17c13ccdb"},
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"db_connection": {:hex, :db_connection, "2.10.2", "ae391e803a5adff104da913c2fc1c0c14a37f8b10001dcef568796e1fb7bf95c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "510b14482330f1af6490a2fa0efd8d4f1435d1529b165647df22ac0f2df0fa93"},
|
||||
"decimal": {:hex, :decimal, "3.1.1", "430d87b04011ce6cbd4fd205be758311a81f87d552d40904abd00f015935b1d0", [:mix], [], "hexpm", "c5f25f2ced74a0587d03e6023f595db8e924c9d3922c8c8ffd9edfc4498cf1f6"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"},
|
||||
"ecto": {:hex, :ecto, "3.14.0", "2fa64521eebfcb2670d907a86e4ad947290e9933706bb315e6fb5c21b172cb26", [:mix], [{:decimal, "~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "130d69ffb4285f9ce4792b65dfbb994fd13ea4cbc3cbea2524b199aa3de84af3"},
|
||||
"ecto": {:hex, :ecto, "3.14.1", "7b740d87bdf45996aa0c2c2e081640906f10caa7ce5ba328fd294c7d49d0cc6f", [:mix], [{:decimal, "~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "24b991956796700f467d0a3ef3d303138a3ef9ddddf8b98f43758ee067b20a30"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.14.0", "06446ab8410d2f85bfbb80857ee224ab3b693700cbb38f6535d507449a627b2e", [:mix], [{:db_connection, "~> 2.9", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.14.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.8", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f4d8d36faf294c9417b5a37ec7ac8217ee2abdef5fcf197ba690f361548d3949"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"},
|
||||
"erlex": {:hex, :erlex, "0.2.9", "7debbbaa9f4f368b8cd648983e0f1d7963028508e9c59e9d4ed504e94ef52a55", [:mix], [], "hexpm", "8cfffc0ec7159e6d73de2ab28a588064de80f88b2798d5cbe4482cbbc200178b"},
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
"lazy_html": {:hex, :lazy_html, "0.1.11", "136c8e9cd616b4f4e9c1562daa683880891120b759606dc4c3b6b18058ba5d79", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.9.0", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:fine, "~> 0.1.0", [hex: :fine, repo: "hexpm", optional: false]}], "hexpm", "3b1be592929c31eca1a21673d25696e5c14cddfe922d9d1a3e3b48be4163883b"},
|
||||
"libcluster": {:hex, :libcluster, "3.5.0", "5ee4cfde4bdf32b2fef271e33ce3241e89509f4344f6c6a8d4069937484866ba", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ebf6561fcedd765a4cd43b4b8c04b1c87f4177b5fb3cbdfe40a780499d72f743"},
|
||||
"mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"},
|
||||
"mint": {:hex, :mint, "1.9.1", "3bc120b743ed2e99ad920910f2613e9faebabb2257731b0e2ea4d8ccd9eceede", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "831101bd560b086316fab5f7adb21a4f3455717d8e4bc8368b052e09aa9163e0"},
|
||||
"mint": {:hex, :mint, "1.9.3", "3337184d69179695c7a9f1714d92c11e629d36c8c037a21cf490131d3d150554", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5f7c9342480c069dbbc4eeac3490303c9e01870ff01a7f1d29b6107054fc1e74"},
|
||||
"mix_test_watch": {:hex, :mix_test_watch, "1.4.0", "d88bcc4fbe3198871266e9d2f00cd8ae350938efbb11d3fa1da091586345adbb", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "2b4693e17c8ead2ef56d4f48a0329891e8c2d0d73752c0f09272a2b17dc38d1b"},
|
||||
"mox": {:hex, :mox, "1.2.0", "a2cd96b4b80a3883e3100a221e8adc1b98e4c3a332a8fc434c39526babafd5b3", [:mix], [{:nimble_ownership, "~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}], "hexpm", "c7b92b3cc69ee24a7eeeaf944cd7be22013c52fcb580c1f33f50845ec821089a"},
|
||||
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
||||
|
|
@ -46,19 +46,19 @@
|
|||
"phoenix_html": {:hex, :phoenix_html, "4.3.0", "d3577a5df4b6954cd7890c84d955c470b5310bb49647f0a114a6eeecc850f7ad", [:mix], [], "hexpm", "3eaa290a78bab0f075f791a46a981bbe769d94bc776869f4f3063a14f30497ad"},
|
||||
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.8.7", "405880012cb4b706f26dd1c6349125bfc903fb9e44d1ea668adaf4e04d4884b7", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:ecto_sqlite3_extras, "~> 1.1.7 or ~> 1.2.0", [hex: :ecto_sqlite3_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.19 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "3a8625cab39ec261d48a13b7468dc619c0ede099601b084e343968309bd4d7d7"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.6.2", "b18b0773a1ba77f28c52decbb0f10fd1ac4d3ae5b8632399bbf6986e3b665f62", [:mix], [{:file_system, "~> 0.2.10 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "d1f89c18114c50d394721365ffb428cce24f1c13de0467ffa773e2ff4a30d5b9"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "1.1.32", "4977ad4cfab7868f3d2ba390a2cd6c62412614d48f798e85785602281a0a3827", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0-rc", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c9d8e76373414259ec5699a809991d1324808bee1d297730599e273282cee34"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "1.2.7", "d0f20871681216598e78baccd4f66d8686fdb8007821989bab508d293a3ed9ad", [:mix], [{:igniter, ">= 0.6.16 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:lazy_html, "~> 0.1.0", [hex: :lazy_html, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0 or ~> 1.8.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "61e97938a4fcca6d6f2c836925623abf2f52a572cc8c6085e4074f3f6337e0eb"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.2.0", "ff3a5616e1bed6804de7773b92cbccfc0b0f473faf1f63d7daf1206c7aeaaa6f", [:mix], [], "hexpm", "adc313a5bf7136039f63cfd9668fde73bba0765e0614cba80c06ac9460ff3e96"},
|
||||
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
|
||||
"plug": {:hex, :plug, "1.20.2", "adbee2441232412e37fbb357fd5e4cd533fdd253b29f2e1992262b0f1fb01462", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b16baf55877d60891002ffc1ce0b3ff7d6f30a38a23e02e4d4293c4ac266f136"},
|
||||
"plug": {:hex, :plug, "1.20.3", "56c480c633ec2ce10140e236e15233bf576e1d323887d7c96711bd02ab5160db", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "be266aee1b8536ef6409d58cf39a3121319f0ec47cfa1b24024485aa0e76ad76"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
|
||||
"postgrex": {:hex, :postgrex, "0.22.2", "4aec14df2a72722aee92492566edbeeb44e233ecb86b1915d03136297ef1385d", [:mix], [{:db_connection, "~> 2.9", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "8946382ddb06294f56026ac4278b3cc212bac8a2c82ed68b4087819ed1abc53b"},
|
||||
"postgrex": {:hex, :postgrex, "0.22.3", "bf65941737ee7a9adbe4a64c91080310d11703da343e8ac9188aacb9eb9f6f02", [:mix], [{:db_connection, "~> 2.9", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "f018c13752b2b46e8d35d7e2d84c3276557cbfd880769109021a1d0ee36c1cfe"},
|
||||
"prom_ex": {:hex, :prom_ex, "1.12.0", "a82cbd5b49964e4d4295ab72a18e007aadd5f4a91630b7c49fad42cc7e49c880", [:mix], [{:absinthe, ">= 1.8.0", [hex: :absinthe, repo: "hexpm", optional: true]}, {:broadway, ">= 1.1.0", [hex: :broadway, repo: "hexpm", optional: true]}, {:ecto, ">= 3.14.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:finch, "~> 0.18", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:oban, ">= 2.10.0", [hex: :oban, repo: "hexpm", optional: true]}, {:octo_fetch, "~> 0.4", [hex: :octo_fetch, repo: "hexpm", optional: false]}, {:peep, "~> 3.0 or ~> 4.0", [hex: :peep, repo: "hexpm", optional: false]}, {:phoenix, ">= 1.7.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, ">= 0.20.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, ">= 1.16.0", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 2.6.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, ">= 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}, {:telemetry_metrics_prometheus_core, "~> 1.2", [hex: :telemetry_metrics_prometheus_core, repo: "hexpm", optional: false]}, {:telemetry_poller, "~> 1.1", [hex: :telemetry_poller, repo: "hexpm", optional: false]}], "hexpm", "6357484941489ba2fee64bb1e9f2a1e86309545304f9e90144e3c10e553c958b"},
|
||||
"req": {:hex, :req, "0.6.2", "b9b2024f35bcf60a92cc8cad2eaaf9d4e7aace463ff74be1afe5986830184413", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.21", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "cc9cd30a2ddd04989929b887178e1610c940456d962c6c3a52df6146d2eef9bf"},
|
||||
"req": {:hex, :req, "0.6.3", "7fe5e68792ff0546e45d5919104fa1764a13694cfe3e48c8a0f32ad051ae77e4", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.21", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "e85b5c6c990e6c3f52bbba68e6f099118f2b8252825f96c7c3636b97a3de307d"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
|
||||
"stream_data": {:hex, :stream_data, "1.3.0", "bde37905530aff386dea1ddd86ecbf00e6642dc074ceffc10b7d4e41dfd6aac9", [:mix], [], "hexpm", "3cc552e286e817dca43c98044c706eec9318083a1480c52ae2688b08e2936e3c"},
|
||||
"stream_data": {:hex, :stream_data, "1.4.0", "026f929db613aabea6208012ae9b8970d3fd5f88b3bdf26831bc536f98c42036", [:mix], [], "hexpm", "2b0ee3a340dcce1c8cf6302a763ee757d1e01c54d6e16d9069062509d68b1dc9"},
|
||||
"styler": {:hex, :styler, "1.11.0", "35010d970689a23c2bcc8e97bd8bf7d20e3561d60c49be84654df5c37d051a9c", [:mix], [], "hexpm", "70f36165d0cf238a32b7a456fdef6a9c72e77e657d7ac4a0ace33aeba3f2b8c0"},
|
||||
"swoosh": {:hex, :swoosh, "1.26.3", "9d8b60077305ce259298d9a1102e5be67cd3c41d1ea930c29e9288af195ca017", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, ">= 1.9.0 and < 5.0.0", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, ">= 6.0.0 and < 8.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c7683d070fe8f8aa9d174e61b01f2d527be73cd8ac40037b7109184941eb569f"},
|
||||
"tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"},
|
||||
"tailwind": {:hex, :tailwind, "0.5.1", "35435b13158c90d37da11e1cfc808755fca1d7b6c5ab87b1b19c5de87e2f0a10", [:mix], [], "hexpm", "c4e26302a59fec72abc5610ecb6ad2116d9aa31f31aab2d4b8eb6e95d25a689c"},
|
||||
"telemetry": {:hex, :telemetry, "1.4.2", "a0cb522801dffb1c49fe6e30561badffc7b6d0e180db1300df759faa22062855", [:rebar3], [], "hexpm", "928f6495066506077862c0d1646609eed891a4326bee3126ba54b60af61febb1"},
|
||||
"telemetry_metrics": {:hex, :telemetry_metrics, "1.1.0", "5bd5f3b5637e0abea0426b947e3ce5dd304f8b3bc6617039e2b5a008adc02f8f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7b79e8ddfde70adb6db8a6623d1778ec66401f366e9a8f5dd0955c56bc8ce67"},
|
||||
"telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.2.1", "c9755987d7b959b557084e6990990cb96a50d6482c683fb9622a63837f3cd3d8", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5e2c599da4983c4f88a33e9571f1458bf98b0cf6ba930f1dc3a6e8cf45d5afb6"},
|
||||
|
|
|
|||
304
nix/shell.nix
Normal file
304
nix/shell.nix
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
{
|
||||
lib,
|
||||
stdenv,
|
||||
mkShell,
|
||||
writeShellScriptBin,
|
||||
# Elixir/Erlang
|
||||
elixir,
|
||||
# Databases
|
||||
postgresql_17,
|
||||
# Build tools for NIF deps (bcrypt_elixir via elixir_make)
|
||||
gcc,
|
||||
gnumake,
|
||||
pkg-config,
|
||||
# Development tools
|
||||
inotify-tools,
|
||||
# LSPs and formatters
|
||||
elixir-ls,
|
||||
nixfmt,
|
||||
shellcheck,
|
||||
# Pre-commit hooks
|
||||
pre-commit-hooks,
|
||||
}:
|
||||
|
||||
let
|
||||
# PostgreSQL with PostGIS extension
|
||||
pg = postgresql_17.withPackages (ps: [
|
||||
ps.postgis
|
||||
]);
|
||||
|
||||
# PostgreSQL data directory (local to project)
|
||||
pgDataDir = ".nix-postgres";
|
||||
pgPort = "5432";
|
||||
pgHost = "localhost";
|
||||
|
||||
# Service management flag
|
||||
servicesFlag = ".nix-services-started";
|
||||
|
||||
# Version file to detect when PG config changes (extensions added/removed, version bump)
|
||||
pgVersionFile = ".nix-postgres-version";
|
||||
|
||||
# Script to start PostgreSQL
|
||||
startServices = writeShellScriptBin "start-services" ''
|
||||
set -e
|
||||
|
||||
echo "🚀 Starting development services..."
|
||||
|
||||
# Check if PG version/extensions changed and reinit if needed.
|
||||
# Must run BEFORE the servicesFlag guard so already-running clusters
|
||||
# get reinitialized when extensions or versions change.
|
||||
pg_needs_reinit=false
|
||||
if [ -d "${pgDataDir}" ] && [ -f "${pgVersionFile}" ]; then
|
||||
if [ "$(cat ${pgVersionFile})" != "${pg}" ]; then
|
||||
echo "⚠️ PostgreSQL configuration changed (extensions or version updated)"
|
||||
pg_needs_reinit=true
|
||||
fi
|
||||
fi
|
||||
if [ -d "${pgDataDir}" ] && [ ! -f "${pgVersionFile}" ]; then
|
||||
pg_needs_reinit=true
|
||||
fi
|
||||
|
||||
if $pg_needs_reinit; then
|
||||
echo "🗑️ Stopping old PostgreSQL and removing cluster..."
|
||||
${pg}/bin/pg_ctl -D ${pgDataDir} stop -m fast 2>/dev/null || true
|
||||
rm -rf ${pgDataDir}
|
||||
rm -f ${servicesFlag}
|
||||
fi
|
||||
|
||||
# Check if already started (with correct version)
|
||||
if [ -f "${servicesFlag}" ]; then
|
||||
echo "✓ Services already running (remove ${servicesFlag} to force restart)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Initialize PostgreSQL if needed
|
||||
if [ ! -d "${pgDataDir}" ]; then
|
||||
echo "📦 Initializing PostgreSQL database..."
|
||||
${pg}/bin/initdb -D ${pgDataDir} -U $USER --encoding=UTF8 --locale=en_US.UTF-8
|
||||
|
||||
# Configure PostgreSQL
|
||||
cat >> ${pgDataDir}/postgresql.conf << EOF
|
||||
# Development configuration
|
||||
# max_connections sized for the test pool (schedulers_online * 16)
|
||||
max_connections = 300
|
||||
shared_buffers = 128MB
|
||||
fsync = off # Faster for development (DO NOT use in production)
|
||||
synchronous_commit = off
|
||||
full_page_writes = off
|
||||
EOF
|
||||
|
||||
# Record current PG version for future change detection
|
||||
echo -n "${pg}" > ${pgVersionFile}
|
||||
fi
|
||||
|
||||
# Check if PostgreSQL is already running on this port
|
||||
if ${pg}/bin/pg_isready -h ${pgHost} -p ${pgPort} > /dev/null 2>&1; then
|
||||
echo "✓ PostgreSQL already running on port ${pgPort}"
|
||||
else
|
||||
# Start PostgreSQL
|
||||
echo "🐘 Starting PostgreSQL on port ${pgPort}..."
|
||||
${pg}/bin/pg_ctl -D ${pgDataDir} -l ${pgDataDir}/logfile -o "-p ${pgPort}" start
|
||||
|
||||
# Wait for PostgreSQL to be ready
|
||||
for i in {1..30}; do
|
||||
if ${pg}/bin/pg_isready -h ${pgHost} -p ${pgPort} > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
if [ $i -eq 30 ]; then
|
||||
echo "❌ PostgreSQL failed to start within 30 seconds"
|
||||
echo " Check ${pgDataDir}/logfile for details"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "✓ PostgreSQL started successfully"
|
||||
fi
|
||||
|
||||
# Create postgres role if it doesn't exist (dev.exs/test.exs connect as postgres)
|
||||
${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -tc \
|
||||
"SELECT 1 FROM pg_roles WHERE rolname='postgres'" | grep -q 1 || \
|
||||
${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -c \
|
||||
"CREATE ROLE postgres WITH SUPERUSER LOGIN PASSWORD 'postgres';"
|
||||
|
||||
# Create development and test databases
|
||||
for db in aprsme_dev aprsme_test; do
|
||||
${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d postgres -tc \
|
||||
"SELECT 1 FROM pg_database WHERE datname='$db'" | grep -q 1 || \
|
||||
${pg}/bin/createdb -h ${pgHost} -p ${pgPort} -U $USER $db
|
||||
done
|
||||
|
||||
# Enable PostGIS extension for dev and test databases
|
||||
for db in aprsme_dev aprsme_test; do
|
||||
${pg}/bin/psql -h ${pgHost} -p ${pgPort} -U $USER -d $db -c \
|
||||
"CREATE EXTENSION IF NOT EXISTS postgis CASCADE;" 2>/dev/null || \
|
||||
echo "⚠️ PostGIS not available for $db (optional)"
|
||||
done
|
||||
|
||||
echo "✓ PostgreSQL started successfully"
|
||||
|
||||
# Mark services as started
|
||||
touch ${servicesFlag}
|
||||
|
||||
echo ""
|
||||
echo "✨ Development environment ready!"
|
||||
echo ""
|
||||
echo "PostgreSQL: ${pgHost}:${pgPort} (databases: aprsme_dev, aprsme_test)"
|
||||
echo ""
|
||||
'';
|
||||
|
||||
# Script to stop PostgreSQL
|
||||
stopServices = writeShellScriptBin "stop-services" ''
|
||||
set -e
|
||||
|
||||
echo "🛑 Stopping development services..."
|
||||
|
||||
# Stop PostgreSQL
|
||||
if [ -d "${pgDataDir}" ]; then
|
||||
${pg}/bin/pg_ctl -D ${pgDataDir} stop -m fast 2>/dev/null || true
|
||||
echo "✓ PostgreSQL stopped"
|
||||
fi
|
||||
|
||||
# Remove services flag
|
||||
rm -f ${servicesFlag}
|
||||
|
||||
echo "✓ Services stopped successfully"
|
||||
'';
|
||||
|
||||
# Pre-commit hooks configuration
|
||||
pre-commit-check = pre-commit-hooks.run {
|
||||
src = ../.;
|
||||
hooks = {
|
||||
# Elixir formatting
|
||||
mix-format = {
|
||||
enable = true;
|
||||
name = "mix format";
|
||||
entry = "mix format --check-formatted";
|
||||
files = "\\.(ex|exs)$";
|
||||
pass_filenames = false;
|
||||
};
|
||||
|
||||
# Credo linting
|
||||
credo = {
|
||||
enable = true;
|
||||
name = "credo";
|
||||
entry = "mix credo --strict";
|
||||
files = "\\.(ex|exs)$";
|
||||
pass_filenames = false;
|
||||
};
|
||||
|
||||
# Nix formatting
|
||||
nixfmt = {
|
||||
enable = true;
|
||||
entry = "${nixfmt}/bin/nixfmt";
|
||||
};
|
||||
|
||||
# Shellcheck for shell scripts
|
||||
shellcheck.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
mkShell {
|
||||
name = "aprsme-dev";
|
||||
|
||||
# Development tools
|
||||
buildInputs = [
|
||||
# Elixir/Erlang
|
||||
elixir
|
||||
|
||||
# Databases (PostgreSQL with PostGIS)
|
||||
pg
|
||||
|
||||
# NIF build tools (bcrypt_elixir)
|
||||
gcc
|
||||
gnumake
|
||||
pkg-config
|
||||
|
||||
# LSPs and formatters
|
||||
elixir-ls
|
||||
nixfmt
|
||||
shellcheck
|
||||
|
||||
# Service management scripts
|
||||
startServices
|
||||
stopServices
|
||||
]
|
||||
++ lib.optionals stdenv.isLinux [
|
||||
# Linux-only tools
|
||||
inotify-tools # For Mix file watching
|
||||
];
|
||||
|
||||
# Environment variables
|
||||
shellHook = ''
|
||||
# Color codes
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Set Mix and Hex home to local directories (avoid polluting $HOME)
|
||||
export MIX_HOME="$PWD/.nix-mix"
|
||||
export HEX_HOME="$PWD/.nix-hex"
|
||||
mkdir -p "$MIX_HOME" "$HEX_HOME"
|
||||
|
||||
# PostgreSQL connection (dev.exs/test.exs connect as postgres:postgres)
|
||||
export PGHOST="${pgHost}"
|
||||
export PGPORT="${pgPort}"
|
||||
export PGUSER="$USER"
|
||||
export DATABASE_URL="ecto://postgres:postgres@${pgHost}:${pgPort}/aprsme_dev"
|
||||
|
||||
# Development environment
|
||||
export MIX_ENV=dev
|
||||
export PHX_HOST=localhost
|
||||
export PORT=4000
|
||||
|
||||
# Erlang shell history
|
||||
export ERL_AFLAGS="-kernel shell_history enabled"
|
||||
|
||||
# Skip heavy setup when running inside direnv (DIRENV_DIR is set).
|
||||
# direnv evaluates the shellHook to load env vars only; running mix,
|
||||
# starting services, or installing pre-commit hooks would block the
|
||||
# prompt and cause nix profile cleanup hangs on macOS.
|
||||
if [ -z "$DIRENV_DIR" ]; then
|
||||
# Running in nix develop (interactive shell)
|
||||
|
||||
# Install Hex and Rebar3 if not already installed
|
||||
mix local.hex --force --if-missing > /dev/null 2>&1
|
||||
mix local.rebar --force --if-missing > /dev/null 2>&1
|
||||
|
||||
# Pre-compile test dependencies so mix test works immediately.
|
||||
# The _build/test tree is ephemeral (cleared when nix devShell changes).
|
||||
MIX_ENV=test mix deps.compile 2>/dev/null || true
|
||||
|
||||
# Auto-start services on first shell entry.
|
||||
# Run in a detached subshell to prevent nix develop from waiting
|
||||
# on daemonized PostgreSQL child processes.
|
||||
if [ ! -f "${servicesFlag}" ]; then
|
||||
( ${startServices}/bin/start-services </dev/null & )
|
||||
fi
|
||||
|
||||
# Install pre-commit hooks
|
||||
${pre-commit-check.shellHook}
|
||||
|
||||
# Welcome message
|
||||
echo ""
|
||||
echo -e "''${BLUE}╔═══════════════════════════════════════════════════════════╗''${NC}"
|
||||
echo -e "''${BLUE}║ ║''${NC}"
|
||||
echo -e "''${BLUE}║''${NC} ''${GREEN}aprs.me Development Environment''${NC} ''${BLUE}║''${NC}"
|
||||
echo -e "''${BLUE}║ ║''${NC}"
|
||||
echo -e "''${BLUE}╚═══════════════════════════════════════════════════════════╝''${NC}"
|
||||
echo ""
|
||||
echo -e "''${GREEN}Available commands:''${NC}"
|
||||
echo " mix phx.server - Start Phoenix development server"
|
||||
echo " mix test - Run test suite"
|
||||
echo " mix format - Format Elixir code"
|
||||
echo " mix credo --strict - Run static analysis"
|
||||
echo " start-services - Start PostgreSQL"
|
||||
echo " stop-services - Stop PostgreSQL"
|
||||
echo " mix ecto.reset - Reset database (drop, create, migrate, seed)"
|
||||
echo ""
|
||||
echo -e "''${GREEN}Services:''${NC}"
|
||||
echo " PostgreSQL: ${pgHost}:${pgPort}"
|
||||
echo ""
|
||||
fi
|
||||
'';
|
||||
}
|
||||
7
shell.nix
Normal file
7
shell.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Compatibility shim for developers using `nix-shell` instead of `nix develop`
|
||||
# This file uses flake-compat to provide the development shell from flake.nix
|
||||
|
||||
(import (fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/35bb57c0c8d8b62bbfd284272c928ceb64ddbde9.tar.gz";
|
||||
sha256 = "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=";
|
||||
}) { src = ./.; }).shellNix.default
|
||||
|
|
@ -881,7 +881,7 @@ defmodule Aprsme.IsTest do
|
|||
|
||||
capture_log(fn ->
|
||||
assert {:noreply, same_state} = Aprsme.Is.handle_info(:reconnect, state)
|
||||
refute is_nil(same_state.failure_started_at)
|
||||
assert same_state.failure_started_at
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue