@page "/{Owner}/{Name}/commit/{Sha}"
@inject IRepositoryService RepositoryService
@inject IGitService GitService
@using Forge.Core.Models

<PageTitle>@(commit?.Sha[..7]) - @Owner/@Name - Forge</PageTitle>

@if (repo == null || commit == null)
{
    <p>Loading...</p>
}
else
{
    <div class="repo-header">
        <h1>
            <a href="/@repo.Owner">@repo.Owner</a> / <a href="/@repo.Owner/@repo.Name"><strong>@repo.Name</strong></a>
        </h1>
    </div>

    <div class="commit-detail">
        <div class="commit-header">
            <h2>@commit.Message.Split('\n')[0]</h2>
            <code class="sha">@commit.Sha</code>
        </div>
        @if (commit.Message.Split('\n').Length > 1)
        {
            <div class="commit-body">@string.Join('\n', commit.Message.Split('\n').Skip(1))</div>
        }
        <div class="commit-meta">
            <span><strong>@commit.Author</strong> committed @RelativeTime(commit.AuthorDate)</span>
        </div>
    </div>

    @if (commit.Changes?.Any() == true)
    {
        @foreach (var change in commit.Changes)
        {
            <div class="diff-file">
                <div class="diff-header">
                    <span class="change-type @change.ChangeType.ToString().ToLower()">@change.ChangeType.ToString()[0]</span>
                    <a href="/@repo.Owner/@repo.Name/blob/@commit.Sha/@change.Path">@change.Path</a>
                    <span class="diff-stats">
                        @if (change.Additions > 0)
                        {
                            <span class="additions">+@change.Additions</span>
                        }
                        @if (change.Deletions > 0)
                        {
                            <span class="deletions">-@change.Deletions</span>
                        }
                    </span>
                </div>
                @if (!string.IsNullOrEmpty(change.Diff))
                {
                    <pre class="diff-content">
@foreach (var line in change.Diff.Split('\n'))
{
    @if (line.StartsWith("@@") || line.StartsWith("diff --git") || line.StartsWith("index ") || line.StartsWith("--- ") || line.StartsWith("+++ "))
    {
        <span class="diff-line-header">@line</span>
    }
    else if (line.StartsWith("+") && !line.StartsWith("+++"))
    {
        <span class="diff-line-add">@line</span>
    }
    else if (line.StartsWith("-") && !line.StartsWith("---"))
    {
        <span class="diff-line-del">@line</span>
    }
    else
    {
        @line
    }
    <text>
</text>
}
                    </pre>
                }
            </div>
        }
    }
}

@code {
    [Parameter] public string Owner { get; set; } = "";
    [Parameter] public string Name { get; set; } = "";
    [Parameter] public string Sha { get; set; } = "";

    private Repository? repo;
    private CommitDetail? commit;

    protected override async Task OnInitializedAsync()
    {
        repo = await RepositoryService.GetByOwnerAndNameAsync(Owner, Name);
        if (repo != null)
        {
            commit = await GitService.GetCommitAsync(repo, Sha);
        }
    }

    private static string RelativeTime(DateTime date)
    {
        var span = DateTime.UtcNow - date;
        if (span.TotalDays > 365) return $"{(int)(span.TotalDays / 365)} years ago";
        if (span.TotalDays > 30) return $"{(int)(span.TotalDays / 30)} months ago";
        if (span.TotalDays > 1) return $"{(int)span.TotalDays} days ago";
        if (span.TotalHours > 1) return $"{(int)span.TotalHours} hours ago";
        if (span.TotalMinutes > 1) return $"{(int)span.TotalMinutes} minutes ago";
        return "just now";
    }
}
An unhandled error has occurred. Reload 🗙