Files
archived-hipudding-teslamate/lib/teslamate_web/live/car_live/summary.ex
JakobLichterfeld 2a922e321c feat: update to Phoenix HTML 4.1, bump dependencies (#4277)
* feat: update to Phenix HTML 4.1

* fix: updating to the new Gettext.Backend approach

* chore: update pot files ro locale version 45.0.0

* fix: downgrade cloack back to 1.1.2

* revert: merge of mix.lock

* fix: new syntax for field name generation for phx-feedback-for

* Revert "fix: new syntax for field name generation for phx-feedback-for"

This reverts commit 4d95e4f1c9367d2d5c606ced2190ab23edcb971b.

* fix: downgrade floki back to 0.35.2

* Revert "fix: downgrade floki back to 0.35.2"

This reverts commit a4f0b6bf4b32099d89003c3d20f72333d510e109.

* fix: ensure floki nil is handled

* style: linter findings

* Revert "fix: ensure floki nil is handled"

* fix: new syntax for field name generation for phx-feedback-for

* debug: floki paramter error

* Revert "debug: floki paramter error"

This reverts commit 61920267edf5186b593920bde7d87e8b30af55aa.

* fix: Remove unnecessary code in settings_test.exs which breaks floki 0.36+
2024-10-27 08:17:49 +01:00

159 lines
5.0 KiB
Elixir

defmodule TeslaMateWeb.CarLive.Summary do
use TeslaMateWeb, :live_view
use Gettext, backend: TeslaMateWeb.Gettext
alias TeslaMate.Vehicles.Vehicle.Summary
alias TeslaMate.Vehicles.Vehicle
alias TeslaMate.{Vehicles, Convert}
on_mount {TeslaMateWeb.InitAssigns, :locale}
@impl true
def mount(_params, %{"summary" => %Summary{car: car} = summary} = session, socket) do
if connected?(socket) do
send(self(), :update_duration)
send(self(), {:status, Vehicle.busy?(car.id)})
:ok = Vehicles.subscribe_to_summary(car.id)
:ok = Vehicles.subscribe_to_fetch(car.id)
end
assigns = %{
car: car,
summary: summary,
fetch_status: Vehicle.busy?(car.id),
fetch_start: 0,
fetch_timer: nil,
settings: session["settings"],
translate_state: &translate_state/1,
duration: humanize_duration(summary.since),
error: nil,
error_timeout: nil,
loading: false
}
{:ok, assign(socket, assigns)}
end
@impl true
def handle_event("suspend_logging", _val, socket) do
cancel_timer(socket.assigns.error_timeout)
send(self(), :suspend_logging)
{:noreply, assign(socket, loading: true)}
end
def handle_event("resume_logging", _val, socket) do
send(self(), :resume_logging)
{:noreply, assign(socket, loading: true)}
end
@impl true
def handle_info(:update_duration, socket) do
Process.send_after(self(), :update_duration, :timer.seconds(1))
{:noreply, assign(socket, duration: humanize_duration(socket.assigns.summary.since))}
end
def handle_info(:resume_logging, socket) do
:ok = Vehicles.resume_logging(socket.assigns.car.id)
{:noreply, socket}
end
def handle_info(:suspend_logging, socket) do
assigns =
case Vehicles.suspend_logging(socket.assigns.car.id) do
:ok ->
%{error: nil, error_timeout: nil, loading: false}
{:error, reason} ->
%{
error: error_to_str(reason),
error_timeout: Process.send_after(self(), :hide_error, 5_000),
loading: false
}
end
{:noreply, assign(socket, assigns)}
end
def handle_info(:hide_error, socket) do
{:noreply, assign(socket, error: nil, error_timeout: nil)}
end
def handle_info(%Summary{since: since} = summary, socket) do
{:noreply,
assign(socket, summary: summary, duration: humanize_duration(since), loading: false)}
end
def handle_info({:status, true}, socket) do
cancel_timer(socket.assigns.fetch_timer)
assigns = %{
fetch_status: true,
fetch_start: System.monotonic_time(),
fetch_timer: nil
}
{:noreply, assign(socket, assigns)}
end
# Note: this must be smaller than the @driving_interval
@min_spinner_visibility_ms 1000
def handle_info({:status, false}, socket) do
fetch_duration =
(System.monotonic_time() - socket.assigns.fetch_start) /
System.convert_time_unit(1, :millisecond, :native)
assigns =
case @min_spinner_visibility_ms - fetch_duration do
diff when 0 < diff ->
%{fetch_timer: Process.send_after(self(), :set_status_to_false, round(diff))}
_ ->
%{fetch_status: false}
end
{:noreply, assign(socket, assigns)}
end
def handle_info(:set_status_to_false, socket) do
{:noreply, assign(socket, fetch_status: false)}
end
defp translate_state(:start), do: ""
defp translate_state(:driving), do: gettext("driving")
defp translate_state(:charging), do: gettext("charging")
defp translate_state(:updating), do: gettext("updating")
defp translate_state(:suspended), do: gettext("falling asleep")
defp translate_state(:online), do: gettext("online")
defp translate_state(:offline), do: gettext("offline")
defp translate_state(:asleep), do: gettext("asleep")
defp translate_state(:unavailable), do: gettext("unavailable")
defp error_to_str(:unlocked), do: gettext("Car is unlocked")
defp error_to_str(:doors_open), do: gettext("Doors are open")
defp error_to_str(:trunk_open), do: gettext("Trunk is open")
defp error_to_str(:sentry_mode), do: gettext("Sentry mode is enabled")
defp error_to_str(:preconditioning), do: gettext("Preconditioning")
defp error_to_str(:dogmode), do: gettext("Dog mode is enabled")
defp error_to_str(:user_present), do: gettext("Driver present")
defp error_to_str(:downloading_update), do: gettext("Downloading update")
defp error_to_str(:update_in_progress), do: gettext("Update in progress")
defp error_to_str(:timeout), do: gettext("Timeout")
defp error_to_str(_other), do: gettext("An error occurred")
defp cancel_timer(nil), do: :ok
defp cancel_timer(ref) when is_reference(ref), do: Process.cancel_timer(ref)
defp humanize_duration(nil), do: nil
defp humanize_duration(date) do
case DateTime.utc_now() |> DateTime.diff(date, :second) do
dur when dur < 5 -> nil
dur when dur > 60 -> dur |> Convert.sec_to_str() |> Enum.reject(&String.ends_with?(&1, "s"))
dur -> dur |> Convert.sec_to_str()
end
end
end