|
| 1 | +defmodule DiffWeb.DiffComponent do |
| 2 | + use DiffWeb, :live_component |
| 3 | + |
| 4 | + def render(assigns) do |
| 5 | + ~H""" |
| 6 | + <div class="ghd-file"> |
| 7 | + <div class="ghd-file-header"> |
| 8 | + <span class={"ghd-file-status ghd-file-status-#{diff_status(@diff)}"}> |
| 9 | + <%= diff_status(@diff) %> |
| 10 | + </span> |
| 11 | + <%= file_header(@diff, diff_status(@diff)) %> |
| 12 | + <span class="collapse-diff"><svg xmlns="http://www.w3.org/2000/svg" width="10" height="16" viewBox="0 0 10 16"><path fill-rule="evenodd" d="M10 10l-1.5 1.5L5 7.75 1.5 11.5 0 10l5-5 5 5z"/></svg></span> |
| 13 | + <span class="reveal-diff"><svg xmlns="http://www.w3.org/2000/svg" width="10" height="16" viewBox="0 0 10 16"><path fill-rule="evenodd" d="M5 11L0 6l1.5-1.5L5 8.25 8.5 4.5 10 6l-5 5z"/></svg></span> |
| 14 | + </div> |
| 15 | + <div class="ghd-diff"> |
| 16 | + <table class="ghd-diff"> |
| 17 | + <%= for chunk <- @diff.chunks do %> |
| 18 | + <tr class="ghd-chunk-header"> |
| 19 | + <td class="ghd-line-number"> |
| 20 | + <div class="ghd-line-number-from"> </div> |
| 21 | + <div class="ghd-line-number-to"></div> |
| 22 | + </td> |
| 23 | + <td class="ghd-text"> |
| 24 | + <div class="ghd-text-internal"><%= chunk.header %></div> |
| 25 | + </td> |
| 26 | + </tr> |
| 27 | + <%= for line <- chunk.lines do %> |
| 28 | + <tr id={line_id(@diff, line)} class={"ghd-line ghd-line-type-#{line_type(line)}"}> |
| 29 | + <td class="ghd-line-number"> |
| 30 | + <div class="ghd-line-number-from"> |
| 31 | + <%= line_number(line.from_line_number) %> |
| 32 | + </div> |
| 33 | + <div class="ghd-line-number-to"> |
| 34 | + <%= line_number(line.to_line_number) %> |
| 35 | + </div> |
| 36 | + </td> |
| 37 | + <td class="ghd-text"> |
| 38 | + <div class="ghd-text-user"><%= line_text(line.text) %></div> |
| 39 | + </td> |
| 40 | + </tr> |
| 41 | + <% end %> |
| 42 | + <% end %> |
| 43 | + </table> |
| 44 | + </div> |
| 45 | + </div> |
| 46 | + """ |
| 47 | + end |
| 48 | + |
| 49 | + defp file_header(diff, status) do |
| 50 | + from = diff.from |
| 51 | + to = diff.to |
| 52 | + |
| 53 | + case status do |
| 54 | + "changed" -> from |
| 55 | + "renamed" -> "#{from} -> #{to}" |
| 56 | + "removed" -> from |
| 57 | + "added" -> to |
| 58 | + end |
| 59 | + end |
| 60 | + |
| 61 | + defp diff_status(diff) do |
| 62 | + from = diff.from |
| 63 | + to = diff.to |
| 64 | + |
| 65 | + cond do |
| 66 | + !from -> "added" |
| 67 | + !to -> "removed" |
| 68 | + from == to -> "changed" |
| 69 | + true -> "renamed" |
| 70 | + end |
| 71 | + end |
| 72 | + |
| 73 | + defp line_number(ln) when is_nil(ln), do: "" |
| 74 | + defp line_number(ln), do: to_string(ln) |
| 75 | + |
| 76 | + defp line_id(diff, line) do |
| 77 | + hash = :erlang.phash2({diff.from, diff.to}) |
| 78 | + ln = "-#{line.from_line_number}-#{line.to_line_number}" |
| 79 | + [to_string(hash), ln] |
| 80 | + end |
| 81 | + |
| 82 | + defp line_type(line), do: to_string(line.type) |
| 83 | + |
| 84 | + defp line_text("+" <> text), |
| 85 | + do: [content_tag(:span, "+ ", class: "ghd-line-status"), content_tag(:span, text)] |
| 86 | + |
| 87 | + defp line_text("-" <> text), |
| 88 | + do: [content_tag(:span, "- ", class: "ghd-line-status"), content_tag(:span, text)] |
| 89 | + |
| 90 | + defp line_text(" " <> text), |
| 91 | + do: [content_tag(:span, " ", class: "ghd-line-status"), content_tag(:span, text)] |
| 92 | + |
| 93 | + defp line_text(text), do: [content_tag(:span, text)] |
| 94 | +end |
0 commit comments