postland/lib/postland_web/live/profile_live.ex
2024-10-26 16:51:05 -05:00

114 lines
3.6 KiB
Elixir

defmodule PostlandWeb.ProfileLive do
use PostlandWeb, :live_view
alias Postland.Accounts.User
alias Postland.Repo
def render(assigns) do
~H"""
<div class="flex items-start space-x-4">
<div>
<img
class="h-16 w-16 rounded-full drop-shadow-lg"
src={@account.icon || url(~p"/images/avatar.png")}
alt=""
/>
<.form for={@form} phx-submit="avatar" phx-change="avatar">
<.live_file_input :if={@editing} upload={@uploads.avatar} />
</.form>
</div>
<div class="flex flex-col bg-white rounded-lg shadow container">
<.form for={@form} id="profile-form" phx-change="validate" phx-submit="submit">
<div class="p-4">
<h2 :if={!@editing} class="font-bold inline-block"><%= @account.name %></h2>
<span :if={!@editing} class="ml-2 text-gray-500">
@<%= @account.username %>@<%= @host %>
</span>
<.input :if={@editing} field={@form[:name]} label="Display Name" />
</div>
<hr />
<div class="p-4">
<p :if={!@editing} class="text-gray-500 text-sm">
<%= {:safe, Earmark.as_html!(@account.summary || "")} %>
</p>
<.input :if={@editing} field={@form[:summary]} type="textarea" label="Bio" />
</div>
</.form>
<hr />
<div :if={assigns[:current_user]} class="text-right p-4">
<.button :if={!@editing} phx-click="edit">Edit Profile</.button>
<.button :if={@editing} phx-click="edit" form="profile-form">Save Profile</.button>
</div>
</div>
</div>
"""
end
def mount(_params, _session, socket) do
%{host: host} = URI.parse(Postland.my_actor_id())
account = Postland.Accounts.solo_user()
form = account |> User.profile_changeset(%{}) |> to_form()
socket =
socket
|> assign(account: account, host: host, editing: false, form: form)
|> allow_upload(:avatar,
accept: ~w(.jpg .jpeg .png),
progress: &handle_progress/3,
auto_upload: true
)
{:ok, socket}
end
def handle_event("edit", _, socket) do
{:noreply, assign(socket, :editing, true)}
end
def handle_event("validate", params, socket) do
changeset = User.profile_changeset(socket.assigns.account, params)
form = to_form(changeset)
{:noreply, assign(socket, form: form)}
end
def handle_event("submit", %{"user" => params}, socket) do
changeset = User.profile_changeset(socket.assigns.account, params)
case Repo.update(changeset) do
{:ok, account} ->
form = account |> User.profile_changeset(%{}) |> to_form()
{:noreply, assign(socket, account: account, editing: false, form: form)}
{:error, changeset} ->
form = to_form(changeset)
{:noreply, socket |> put_flash(:error, "An error occurred.") |> assign(form: form)}
end
end
def handle_event("avatar", _, socket) do
# The actual upload is handled by auto-upload and the handle_progress callback
{:noreply, socket}
end
def handle_progress(:avatar, entry, socket) do
if entry.done? do
uploaded_file =
consume_uploaded_entry(socket, entry, fn meta ->
Postland.Uploads.handle_upload(entry, meta)
end)
changeset = User.icon_changeset(socket.assigns.account, uploaded_file)
case Repo.update(changeset) do
{:ok, account} ->
{:noreply, assign(socket, account: account)}
{:error, _changeset} ->
{:noreply, put_flash(socket, :error, "An error occurred while finishing upload.")}
end
else
{:noreply, socket}
end
end
end