add locale to user settings

This commit is contained in:
shibao 2022-05-05 20:55:59 -04:00
parent 2fc0e2d036
commit 8c77619446
20 changed files with 224 additions and 79 deletions

View File

@ -12,10 +12,8 @@ if System.get_env("PHX_SERVER") && System.get_env("RELEASE_NAME") do
config :lokal, LokalWeb.Endpoint, server: true config :lokal, LokalWeb.Endpoint, server: true
end end
config :lokal, LokalWeb.ViewHelpers, shibao_mode: System.get_env("SHIBAO_MODE") == "true" # Set default locale
config :gettext, :default_locale, System.get_env("LOCALE") || "en_US"
# Set locale
Gettext.put_locale(System.get_env("LOCALE") || "en_US")
maybe_ipv6 = if System.get_env("ECTO_IPV6") == "true", do: [:inet6], else: [] maybe_ipv6 = if System.get_env("ECTO_IPV6") == "true", do: [:inet6], else: []

View File

@ -96,7 +96,7 @@ In `dev` mode, Lokal will listen for these environment variables at runtime.
Defaults to `false`. Defaults to `false`.
- `POOL_SIZE`: Controls the pool size to use with PostgreSQL. Defaults to `10`. - `POOL_SIZE`: Controls the pool size to use with PostgreSQL. Defaults to `10`.
- `REGISTRATION`: Controls if user sign-up should be invite only or set to public. Set to `public` to enable public registration. Defaults to `invite`. - `REGISTRATION`: Controls if user sign-up should be invite only or set to public. Set to `public` to enable public registration. Defaults to `invite`.
- `LOCALE`: Sets a custom locale. Defaults to `en_US`. - `LOCALE`: Sets a custom default locale. Defaults to `en_US`.
## `MIX_ENV=test` ## `MIX_ENV=test`

View File

@ -269,6 +269,35 @@ defmodule Lokal.Accounts do
end end
end end
@doc """
Returns an `%Changeset{}` for changing the user locale.
## Examples
iex> change_user_locale(user)
%Changeset{data: %User{}}
"""
@spec change_user_locale(User.t()) :: Changeset.t(User.t())
def change_user_locale(%{locale: locale} = user), do: User.locale_changeset(user, locale)
@doc """
Updates the user locale.
## Examples
iex> update_user_locale(user, "valid locale")
{:ok, %User{}}
iex> update_user_password(user, "invalid locale")
{:error, %Changeset{}}
"""
@spec update_user_locale(User.t(), locale :: String.t()) ::
{:ok, User.t()} | {:error, Changeset.t(User.t())}
def update_user_locale(user, locale),
do: user |> User.locale_changeset(locale) |> Repo.update()
@doc """ @doc """
Deletes a user. must be performed by an admin or the same user! Deletes a user. must be performed by an admin or the same user!

View File

@ -18,6 +18,7 @@ defmodule Lokal.Accounts.User do
field :hashed_password, :string field :hashed_password, :string
field :confirmed_at, :naive_datetime field :confirmed_at, :naive_datetime
field :role, Ecto.Enum, values: [:admin, :user], default: :user field :role, Ecto.Enum, values: [:admin, :user], default: :user
field :locale, :string
has_many :invites, Invite, on_delete: :delete_all has_many :invites, Invite, on_delete: :delete_all
@ -32,6 +33,7 @@ defmodule Lokal.Accounts.User do
confirmed_at: NaiveDateTime.t(), confirmed_at: NaiveDateTime.t(),
role: atom(), role: atom(),
invites: [Invite.t()], invites: [Invite.t()],
locale: String.t() | nil,
inserted_at: NaiveDateTime.t(), inserted_at: NaiveDateTime.t(),
updated_at: NaiveDateTime.t() updated_at: NaiveDateTime.t()
} }
@ -60,7 +62,7 @@ defmodule Lokal.Accounts.User do
Changeset.t(t() | new_user()) Changeset.t(t() | new_user())
def registration_changeset(user, attrs, opts \\ []) do def registration_changeset(user, attrs, opts \\ []) do
user user
|> cast(attrs, [:email, :password, :role]) |> cast(attrs, [:email, :password, :role, :locale])
|> validate_email() |> validate_email()
|> validate_password(opts) |> validate_password(opts)
end end
@ -185,4 +187,14 @@ defmodule Lokal.Accounts.User do
do: changeset, do: changeset,
else: changeset |> add_error(:current_password, dgettext("errors", "is not valid")) else: changeset |> add_error(:current_password, dgettext("errors", "is not valid"))
end end
@doc """
A changeset for changing the user's locale
"""
@spec locale_changeset(t() | Changeset.t(t()), locale :: String.t() | nil) :: Changeset.t(t())
def locale_changeset(user_or_changeset, locale) do
user_or_changeset
|> cast(%{"locale" => locale}, [:locale])
|> validate_required(:locale)
end
end end

View File

@ -47,6 +47,7 @@ defmodule LokalWeb do
use Phoenix.LiveView, use Phoenix.LiveView,
layout: {LokalWeb.LayoutView, "live.html"} layout: {LokalWeb.LayoutView, "live.html"}
on_mount LokalWeb.InitAssigns
unquote(view_helpers()) unquote(view_helpers())
end end
end end

View File

@ -10,10 +10,11 @@ defmodule LokalWeb.UserSettingsController do
render(conn, "edit.html", page_title: gettext("Settings")) render(conn, "edit.html", page_title: gettext("Settings"))
end end
def update(conn, %{"action" => "update_email"} = params) do def update(%{assigns: %{current_user: user}} = conn, %{
%{"current_password" => password, "user" => user_params} = params "action" => "update_email",
user = conn.assigns.current_user "current_password" => password,
"user" => user_params
}) do
case Accounts.apply_user_email(user, password, user_params) do case Accounts.apply_user_email(user, password, user_params) do
{:ok, applied_user} -> {:ok, applied_user} ->
Accounts.deliver_update_email_instructions( Accounts.deliver_update_email_instructions(
@ -33,14 +34,15 @@ defmodule LokalWeb.UserSettingsController do
|> redirect(to: Routes.user_settings_path(conn, :edit)) |> redirect(to: Routes.user_settings_path(conn, :edit))
{:error, changeset} -> {:error, changeset} ->
render(conn, "edit.html", email_changeset: changeset) conn |> render("edit.html", email_changeset: changeset)
end end
end end
def update(conn, %{"action" => "update_password"} = params) do def update(%{assigns: %{current_user: user}} = conn, %{
%{"current_password" => password, "user" => user_params} = params "action" => "update_password",
user = conn.assigns.current_user "current_password" => password,
"user" => user_params
}) do
case Accounts.update_user_password(user, password, user_params) do case Accounts.update_user_password(user, password, user_params) do
{:ok, user} -> {:ok, user} ->
conn conn
@ -49,12 +51,27 @@ defmodule LokalWeb.UserSettingsController do
|> UserAuth.log_in_user(user) |> UserAuth.log_in_user(user)
{:error, changeset} -> {:error, changeset} ->
render(conn, "edit.html", password_changeset: changeset) conn |> render("edit.html", password_changeset: changeset)
end end
end end
def confirm_email(conn, %{"token" => token}) do def update(
case Accounts.update_user_email(conn.assigns.current_user, token) do %{assigns: %{current_user: user}} = conn,
%{"action" => "update_locale", "user" => %{"locale" => locale}}
) do
case Accounts.update_user_locale(user, locale) do
{:ok, _user} ->
conn
|> put_flash(:info, dgettext("prompts", "Language updated successfully."))
|> redirect(to: Routes.user_settings_path(conn, :edit))
{:error, changeset} ->
conn |> render("edit.html", locale_changeset: changeset)
end
end
def confirm_email(%{assigns: %{current_user: user}} = conn, %{"token" => token}) do
case Accounts.update_user_email(user, token) do
:ok -> :ok ->
conn conn
|> put_flash(:info, dgettext("prompts", "Email changed successfully.")) |> put_flash(:info, dgettext("prompts", "Email changed successfully."))
@ -84,11 +101,10 @@ defmodule LokalWeb.UserSettingsController do
end end
end end
defp assign_email_and_password_changesets(conn, _opts) do defp assign_email_and_password_changesets(%{assigns: %{current_user: user}} = conn, _opts) do
user = conn.assigns.current_user
conn conn
|> assign(:email_changeset, Accounts.change_user_email(user)) |> assign(:email_changeset, Accounts.change_user_email(user))
|> assign(:password_changeset, Accounts.change_user_password(user)) |> assign(:password_changeset, Accounts.change_user_password(user))
|> assign(:locale_changeset, Accounts.change_user_locale(user))
end end
end end

View File

@ -0,0 +1,19 @@
defmodule LokalWeb.InitAssigns do
@moduledoc """
Ensures common `assigns` are applied to all LiveViews attaching this hook.
"""
import Phoenix.LiveView
alias Lokal.Accounts
def on_mount(:default, _params, %{"locale" => locale, "user_token" => user_token}, socket) do
Gettext.put_locale(locale)
socket =
socket
|> assign_new(:current_user, fn -> Accounts.get_user_by_session_token(user_token) end)
{:cont, socket}
end
def on_mount(:default, _params, _session, socket), do: {:cont, socket}
end

View File

@ -10,9 +10,7 @@ defmodule LokalWeb.InviteLive.Index do
alias Phoenix.LiveView.JS alias Phoenix.LiveView.JS
@impl true @impl true
def mount(_params, session, socket) do def mount(_params, _session, %{assigns: %{current_user: current_user}} = socket) do
%{assigns: %{current_user: current_user}} = socket = socket |> assign_defaults(session)
socket = socket =
if current_user |> Map.get(:role) == :admin do if current_user |> Map.get(:role) == :admin do
socket |> display_invites() socket |> display_invites()

View File

@ -4,21 +4,8 @@ defmodule LokalWeb.LiveHelpers do
""" """
import Phoenix.LiveView.Helpers import Phoenix.LiveView.Helpers
import Phoenix.LiveView
alias Lokal.Accounts
alias Phoenix.LiveView.JS alias Phoenix.LiveView.JS
def assign_defaults(socket, %{"user_token" => user_token} = _session) do
socket
|> assign_new(:current_user, fn ->
Accounts.get_user_by_session_token(user_token)
end)
end
def assign_defaults(socket, _session) do
socket
end
@doc """ @doc """
Renders a live component inside a modal. Renders a live component inside a modal.

View File

@ -6,13 +6,8 @@ defmodule LokalWeb.PageLive do
use LokalWeb, :live_view use LokalWeb, :live_view
@impl true @impl true
def mount(_params, session, socket) do def mount(_params, _session, socket) do
socket = {:ok, socket |> assign(page_title: gettext("Home"), query: "", results: %{})}
socket
|> assign_defaults(session)
|> assign(page_title: gettext("Home"), query: "", results: %{})
{:ok, socket}
end end
@impl true @impl true

View File

@ -11,6 +11,17 @@ defmodule LokalWeb.Router do
plug :protect_from_forgery plug :protect_from_forgery
plug :put_secure_browser_headers plug :put_secure_browser_headers
plug :fetch_current_user plug :fetch_current_user
plug :put_user_locale, default: Application.get_env(:gettext, :default_locale, "en_US")
end
defp put_user_locale(%{assigns: %{current_user: %{locale: locale}}} = conn, default: default) do
Gettext.put_locale(locale || default)
conn |> put_session(:locale, locale || default)
end
defp put_user_locale(conn, default: default) do
Gettext.put_locale(default)
conn |> put_session(:locale, default)
end end
pipeline :require_admin do pipeline :require_admin do

View File

@ -30,6 +30,15 @@
<%= password_input(f, :password, required: true, class: "input input-primary col-span-2") %> <%= password_input(f, :password, required: true, class: "input input-primary col-span-2") %>
<%= error_tag(f, :password, "col-span-3") %> <%= error_tag(f, :password, "col-span-3") %>
<%= label(f, :locale, gettext("Language"), class: "title text-lg text-primary-600") %>
<%= select(
f,
:locale,
[{gettext("English"), "en_US"}],
class: "input input-primary col-span-2"
) %>
<%= error_tag(f, :locale) %>
<%= submit(dgettext("actions", "Register"), class: "mx-auto btn btn-primary col-span-3") %> <%= submit(dgettext("actions", "Register"), class: "mx-auto btn btn-primary col-span-3") %>
<% end %> <% end %>

View File

@ -1,17 +1,18 @@
<div class="mx-auto mb-8 max-w-2xl flex flex-col justify-center items-center space-y-4"> <div
class="mx-auto mb-8 max-w-2xl flex flex-col justify-center items-center text-center space-y-4"
>
<h1 class="pb-4 title text-primary-600 text-xl"> <h1 class="pb-4 title text-primary-600 text-xl">
<%= gettext("Settings") %> <%= gettext("Settings") %>
</h1> </h1>
<hr class="hr" /> <hr class="hr" />
<%= form_for @email_changeset, <.form
Routes.user_settings_path(@conn, :update), let={f}
[ for={@email_changeset}
class: action={Routes.user_settings_path(@conn, :update)}
"flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center" class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
], >
fn f -> %>
<h3 class="title text-primary-600 text-lg col-span-3"> <h3 class="title text-primary-600 text-lg col-span-3">
<%= dgettext("actions", "Change email") %> <%= dgettext("actions", "Change email") %>
</h3> </h3>
@ -45,17 +46,16 @@
<%= submit(dgettext("actions", "Change email"), <%= submit(dgettext("actions", "Change email"),
class: "mx-auto btn btn-primary col-span-3" class: "mx-auto btn btn-primary col-span-3"
) %> ) %>
<% end %> </.form>
<hr class="hr" /> <hr class="hr" />
<%= form_for @password_changeset, <.form
Routes.user_settings_path(@conn, :update), let={f}
[ for={@password_changeset}
class: action={Routes.user_settings_path(@conn, :update)}
"flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center" class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
], >
fn f -> %>
<h3 class="title text-primary-600 text-lg col-span-3"> <h3 class="title text-primary-600 text-lg col-span-3">
<%= dgettext("actions", "Change password") %> <%= dgettext("actions", "Change password") %>
</h3> </h3>
@ -101,8 +101,41 @@
<%= submit(dgettext("actions", "Change password"), <%= submit(dgettext("actions", "Change password"),
class: "mx-auto btn btn-primary col-span-3" class: "mx-auto btn btn-primary col-span-3"
) %> ) %>
</.form>
<hr class="hr" />
<.form
let={f}
for={@locale_changeset}
action={Routes.user_settings_path(@conn, :update)}
class="flex flex-col space-y-4 justify-center items-center"
>
<h3 class="title text-primary-600 text-lg">
<%= dgettext("actions", "Change Language") %>
</h3>
<%= if @locale_changeset.action && not @locale_changeset.valid? do %>
<div class="alert alert-danger">
<p>
<%= dgettext("errors", "Oops, something went wrong! Please check the errors below.") %>
</p>
</div>
<% end %> <% end %>
<%= hidden_input(f, :action, name: "action", value: "update_locale") %>
<%= select(f, :locale, [{gettext("English"), "en_US"}, {"Spanish", "es"}],
class: "mx-2 my-1 min-w-md input input-primary"
) %>
<%= error_tag(f, :locale) %>
<%= submit(dgettext("actions", "Change language"),
class: "whitespace-nowrap mx-auto btn btn-primary",
data: [qa: dgettext("prompts", "Are you sure you want to change your language?")]
) %>
</.form>
<hr class="hr" /> <hr class="hr" />
<%= link(dgettext("actions", "Delete User"), <%= link(dgettext("actions", "Delete User"),

View File

@ -13,6 +13,7 @@ defmodule Lokal.MixProject do
deps: deps(), deps: deps(),
dialyzer: [plt_add_apps: [:ex_unit]], dialyzer: [plt_add_apps: [:ex_unit]],
consolidate_protocols: Mix.env() not in [:dev, :test], consolidate_protocols: Mix.env() not in [:dev, :test],
preferred_cli_env: [test: :test],
# ExDoc # ExDoc
name: "Lokal", name: "Lokal",
source_url: "https://gitea.bubbletea.dev/shibao/lokal", source_url: "https://gitea.bubbletea.dev/shibao/lokal",
@ -91,6 +92,7 @@ defmodule Lokal.MixProject do
"dialyzer", "dialyzer",
"credo --strict", "credo --strict",
"format --check-formatted", "format --check-formatted",
"ecto.drop --quiet",
"ecto.create --quiet", "ecto.create --quiet",
"ecto.migrate --quiet", "ecto.migrate --quiet",
"test" "test"

View File

@ -11,8 +11,8 @@ msgid ""
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:16 #: lib/lokal_web/templates/user_settings/edit.html.heex:17
#: lib/lokal_web/templates/user_settings/edit.html.heex:45 #: lib/lokal_web/templates/user_settings/edit.html.heex:46
msgid "Change email" msgid "Change email"
msgstr "" msgstr ""
@ -23,7 +23,7 @@ msgid "Change password"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:108 #: lib/lokal_web/templates/user_settings/edit.html.heex:141
msgid "Delete User" msgid "Delete User"
msgstr "" msgstr ""
@ -92,3 +92,13 @@ msgstr ""
#: lib/lokal_web/live/invite_live/form_component.html.heex:28 #: lib/lokal_web/live/invite_live/form_component.html.heex:28
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:115
msgid "Change Language"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:133
msgid "Change language"
msgstr ""

View File

@ -21,7 +21,7 @@ msgid "Confirm your account"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:33 #: lib/lokal_web/templates/user_settings/edit.html.heex:34
#: lib/lokal_web/templates/user_settings/edit.html.heex:89 #: lib/lokal_web/templates/user_settings/edit.html.heex:89
msgid "Current password" msgid "Current password"
msgstr "" msgstr ""
@ -80,7 +80,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:10 #: lib/lokal_web/controllers/user_settings_controller.ex:10
#: lib/lokal_web/templates/user_settings/edit.html.heex:3 #: lib/lokal_web/templates/user_settings/edit.html.heex:5
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
@ -153,3 +153,8 @@ msgstr ""
#: lib/lokal_web/live/invite_live/form_component.html.heex:24 #: lib/lokal_web/live/invite_live/form_component.html.heex:24
msgid "Uses left" msgid "Uses left"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:128
msgid "English"
msgstr ""

View File

@ -94,7 +94,7 @@ msgid "must be equal to %{number}"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:67 #: lib/lokal_web/controllers/user_settings_controller.ex:84
msgid "Email change link is invalid or it has expired." msgid "Email change link is invalid or it has expired."
msgstr "" msgstr ""
@ -126,8 +126,9 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_registration/new.html.heex:16 #: lib/lokal_web/templates/user_registration/new.html.heex:16
#: lib/lokal_web/templates/user_reset_password/edit.html.heex:16 #: lib/lokal_web/templates/user_reset_password/edit.html.heex:16
#: lib/lokal_web/templates/user_settings/edit.html.heex:22 #: lib/lokal_web/templates/user_settings/edit.html.heex:23
#: lib/lokal_web/templates/user_settings/edit.html.heex:66 #: lib/lokal_web/templates/user_settings/edit.html.heex:66
#: lib/lokal_web/templates/user_settings/edit.html.heex:121
msgid "Oops, something went wrong! Please check the errors below." msgid "Oops, something went wrong! Please check the errors below."
msgstr "" msgstr ""
@ -149,7 +150,7 @@ msgid "Sorry, this invite was not found or expired"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:82 #: lib/lokal_web/controllers/user_settings_controller.ex:99
msgid "Unable to delete user" msgid "Unable to delete user"
msgstr "" msgstr ""
@ -175,22 +176,22 @@ msgid "You must confirm your account and log in to access this page."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal/accounts/user.ex:128 #: lib/lokal/accounts/user.ex:130
msgid "did not change" msgid "did not change"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal/accounts/user.ex:149 #: lib/lokal/accounts/user.ex:151
msgid "does not match password" msgid "does not match password"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal/accounts/user.ex:186 #: lib/lokal/accounts/user.ex:188
msgid "is not valid" msgid "is not valid"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal/accounts/user.ex:82 #: lib/lokal/accounts/user.ex:84
msgid "must have the @ sign and no spaces" msgid "must have the @ sign and no spaces"
msgstr "" msgstr ""

View File

@ -16,12 +16,12 @@ msgid "%{email} confirmed successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:28 #: lib/lokal_web/controllers/user_settings_controller.ex:29
msgid "A link to confirm your email change has been sent to the new address." msgid "A link to confirm your email change has been sent to the new address."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:112 #: lib/lokal_web/templates/user_settings/edit.html.heex:145
msgid "Are you sure you want to delete your account?" msgid "Are you sure you want to delete your account?"
msgstr "" msgstr ""
@ -31,7 +31,7 @@ msgid "Are you sure you want to log out?"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:60 #: lib/lokal_web/controllers/user_settings_controller.ex:77
msgid "Email changed successfully." msgid "Email changed successfully."
msgstr "" msgstr ""
@ -56,7 +56,7 @@ msgid "Password reset successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:47 #: lib/lokal_web/controllers/user_settings_controller.ex:49
msgid "Password updated successfully." msgid "Password updated successfully."
msgstr "" msgstr ""
@ -66,7 +66,7 @@ msgid "Please check your email to verify your account"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:78 #: lib/lokal_web/controllers/user_settings_controller.ex:95
msgid "Your account has been deleted" msgid "Your account has been deleted"
msgstr "" msgstr ""
@ -126,3 +126,13 @@ msgstr ""
#: lib/lokal_web/live/invite_live/form_component.html.heex:30 #: lib/lokal_web/live/invite_live/form_component.html.heex:30
msgid "Saving..." msgid "Saving..."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/lokal_web/templates/user_settings/edit.html.heex:135
msgid "Are you sure you want to change your language?"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/lokal_web/controllers/user_settings_controller.ex:65
msgid "Language updated successfully."
msgstr ""

View File

@ -0,0 +1,9 @@
defmodule Lokal.Repo.Migrations.AddLocaleSetting do
use Ecto.Migration
def change do
alter table("users") do
add :locale, :string
end
end
end

View File

@ -41,7 +41,7 @@ You can use the following environment variables to configure Lokal in
with `docker run -it shibaobun/lokal mix phx.gen.secret` and set for server to start. with `docker run -it shibaobun/lokal mix phx.gen.secret` and set for server to start.
- `REGISTRATION`: Controls if user sign-up should be invite only or set to - `REGISTRATION`: Controls if user sign-up should be invite only or set to
public. Set to `public` to enable public registration. Defaults to `invite`. public. Set to `public` to enable public registration. Defaults to `invite`.
- `LOCALE`: Sets a custom locale. Defaults to `en_US`. - `LOCALE`: Sets a custom default locale. Defaults to `en_US`.
- `SMTP_HOST`: The url for your SMTP email provider. Must be set - `SMTP_HOST`: The url for your SMTP email provider. Must be set
- `SMTP_PORT`: The port for your SMTP relay. Defaults to `587`. - `SMTP_PORT`: The port for your SMTP relay. Defaults to `587`.
- `SMTP_USERNAME`: The username for your SMTP relay. Must be set! - `SMTP_USERNAME`: The username for your SMTP relay. Must be set!