forked from shibao/cannery
		
	add locale to user settings
This commit is contained in:
		| @@ -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: [] | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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` | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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! | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								lib/lokal_web/live/init_assigns.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/lokal_web/live/init_assigns.ex
									
									
									
									
									
										Normal 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 | ||||||
| @@ -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() | ||||||
|   | |||||||
| @@ -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. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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 %> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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"), | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								mix.exs
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								mix.exs
									
									
									
									
									
								
							| @@ -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" | ||||||
|   | |||||||
| @@ -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 "" | ||||||
|   | |||||||
| @@ -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 "" | ||||||
|   | |||||||
| @@ -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 "" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 "" | ||||||
|   | |||||||
| @@ -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 | ||||||
| @@ -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! | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user