Files
archived-hipudding-teslamate/lib/teslamate_web/live/settings_live/index.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

187 lines
5.4 KiB
Elixir

defmodule TeslaMateWeb.SettingsLive.Index do
use TeslaMateWeb, :live_view
require Logger
alias TeslaMate.Settings.{GlobalSettings, CarSettings}
alias TeslaMate.{Settings, Updater, Api}
on_mount {TeslaMateWeb.InitAssigns, :locale}
@impl true
def mount(_params, %{"settings" => settings}, socket) do
assigns = %{
addresses_migrated?: addresses_migrated?(),
car_settings: Settings.get_car_settings() |> prepare(),
car: nil,
global_settings: settings |> prepare(),
update: Updater.get_update(),
refreshing_addresses?: nil,
refresh_error: nil,
page_title: gettext("Settings")
}
{:ok, assign(socket, assigns)}
end
@impl true
def handle_params(params, _uri, socket) do
%{car_settings: settings, car: car} = socket.assigns
car =
with id when not is_nil(id) <- Map.get(params, "car"),
{id, ""} <- Integer.parse(id),
true <- Map.has_key?(settings, id) do
id
else
_ -> car || settings |> Map.keys() |> List.first()
end
{:noreply, assign(socket, car: car)}
end
@impl true
def handle_event("car", %{"id" => id}, socket) do
{:noreply, add_params(socket, car: id)}
end
def handle_event("change", %{"global_settings" => %{"ui" => ui}}, %{assigns: %{locale: lo}} = s)
when ui != lo do
{:noreply, redirect(s, to: Routes.live_path(s, __MODULE__, locale: ui))}
end
def handle_event("change", %{"global_settings" => params}, %{assigns: assigns} = socket) do
settings = fn ->
case Settings.update_global_settings(assigns.global_settings.original, params) do
{:error, %Ecto.Changeset{} = changeset} ->
%{global_settings: Map.put(assigns.global_settings, :changeset, changeset)}
{:error, reason} ->
Logger.warning("Updating settings failed: #{inspect(reason, pretty: true)}")
%{
refresh_error:
gettext(
"There was a problem retrieving data from OpenStreetMap. Please try again later."
)
}
{:ok, settings} ->
%{global_settings: prepare(settings)}
end
end
socket =
if params["language"] != nil and params["language"] != assigns.global_settings.original do
me = self()
spawn_link(fn -> send(me, {:assigns, settings.()}) end)
assign(socket, refreshing_addresses?: true)
else
assign(socket, settings.())
end
{:noreply, socket}
end
def handle_event("change", params, %{assigns: %{car_settings: settings, car: id}} = socket) do
params = params["car_settings_#{id}"]
settings =
get_in(settings, [id, :original])
|> Settings.update_car_settings(params)
|> case do
{:error, changeset} ->
Logger.warning(inspect(changeset))
put_in(settings, [id, :changeset], changeset)
{:ok, car_settings} ->
settings
|> put_in([id, :original], car_settings)
|> put_in([id, :changeset], Settings.change_car_settings(car_settings))
end
{:noreply, assign(socket, :car_settings, settings)}
end
def handle_event("sign_out", _params, socket) do
:ok = Api.sign_out()
{:noreply, redirect(socket, to: Routes.car_path(socket, :index))}
end
@impl true
def handle_info({:assigns, assigns}, socket) do
socket =
socket
|> assign(refreshing_addresses?: false)
|> assign(assigns)
{:noreply, socket}
end
def handle_info(msg, socket) do
Logger.debug("Unexpected message: #{inspect(msg, pretty: true)}")
{:noreply, socket}
end
# Private
@language_tags (GlobalSettings.supported_languages() ++
[
{"Norwegian", "nb"},
{"Chinese (simplified)", "zh_Hans"},
{"Chinese (traditional)", "zh_Hant"}
])
|> Enum.map(fn {key, val} -> {val, key} end)
|> Enum.into(%{})
@supported_ui_languages TeslaMateWeb.Cldr.known_locale_names()
|> Enum.reject(&(&1 in [:zh]))
|> Enum.map(&String.replace(to_string(&1), "-", "_"))
|> Enum.map(&{Map.get(@language_tags, &1, &1), &1})
|> Enum.sort_by(&elem(&1, 0))
defp supported_ui_languages, do: @supported_ui_languages
defp addresses_migrated? do
alias TeslaMate.Log.{Drive, ChargingProcess}
alias TeslaMate.Repo
import Ecto.Query
count_drives =
from(d in Drive,
select: count(),
where:
(is_nil(d.start_address_id) or is_nil(d.end_address_id)) and
(not is_nil(d.start_position_id) and not is_nil(d.end_position_id))
)
count_charges =
from(c in ChargingProcess,
select: count(),
where: is_nil(c.address_id) and not is_nil(c.position_id)
)
[d, c] =
count_drives
|> union_all(^count_charges)
|> Repo.all()
d + c == 0
end
defp add_params(socket, params) do
push_navigate(socket, to: Routes.live_path(socket, __MODULE__, params), replace: true)
end
defp prepare(%GlobalSettings{} = settings) do
%{original: settings, changeset: Settings.change_global_settings(settings)}
end
defp prepare(settings) do
Enum.reduce(settings, %{}, fn %CarSettings{car: car} = s, acc ->
Map.put(acc, car.id, %{original: s, changeset: Settings.change_car_settings(s)})
end)
end
end