defmodule GitGudWeb.RepoLive.Log do
use GitGudWeb, :live_view
alias GitGud.Git
alias GitGud.Repositories
alias GitGud.Repositories.Storage
@page_size 30
@impl true
def mount(%{"owner" => owner, "name" => name, "ref" => ref}, _session, socket) do
repo =
Repositories.get_repository_by_path!(owner, name)
|> GitGud.Repo.preload([:owner, :organization])
{:ok, head_sha} = Repositories.resolve(repo, ref)
{:ok, commits} = Repositories.list_commits(repo, head_sha, limit: @page_size, skip: 0)
{:ok,
socket
|> assign(:repo, repo)
|> assign(:handle, Storage.repo_handle(repo))
|> GitGudWeb.RepoLive.Header.assign_chrome(repo)
|> assign(:ref, ref)
|> assign(:head_sha, head_sha)
|> assign(:skip, 0)
|> stream(:commits, Enum.map(commits, &decorate/1))
|> assign(:page_title, "#{owner}/#{name}: commits")}
end
defp decorate(commit) do
Map.merge(commit, %{
id: Git.to_hex(commit.sha),
short: Git.short(commit.sha),
title: commit.message |> String.split("\n", parts: 2) |> hd()
})
end
@impl true
def handle_event("load_more", _params, socket) do
repo = socket.assigns.repo
skip = socket.assigns.skip + @page_size
{:ok, commits} =
Repositories.list_commits(repo, socket.assigns.head_sha,
limit: @page_size,
skip: skip
)
{:noreply,
socket
|> assign(:skip, skip)
|> stream(:commits, Enum.map(commits, &decorate/1), at: -1)}
end
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="space-y-4">
<GitGudWeb.RepoLive.Header.header
repo={@repo}
handle={@handle}
current_scope={@current_scope}
has_packages?={@has_packages?}
can_admin?={@can_admin?}
latest_run={@latest_run}
/>
<h1 class="text-xl font-semibold">
<span class="font-normal">commits on {@ref}</span>
</h1>
<ul id="commits" phx-update="stream" class="divide-y divide-base-300">
<li :for={{id, c} <- @streams.commits} id={id} class="py-3">
<div class="flex items-baseline justify-between gap-3">
<.link
navigate={~p"/r/#{@handle}/#{@repo.name}/commit/#{c.id}"}
class="font-medium link link-hover"
>
{c.title}
</.link>
<span class="text-xs font-mono opacity-60">{c.short}</span>
</div>
<p class="text-xs opacity-60">
{c.author_name} · {format_dt(c.committed_at)}
</p>
<.commit_status_badges repo={@repo} sha={c.id} class="mt-1" />
</li>
</ul>
<button type="button" class="btn btn-sm" phx-click="load_more">Load more</button>
</div>
</Layouts.app>
"""
end
defp format_dt(nil), do: "?"
defp format_dt(dt), do: Calendar.strftime(dt, "%Y-%m-%d %H:%M")
end
2.9 KiB · text
5af55d9