Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/pages: show co-authors and committers in commit messages

in smaller views of a commit, such as logs, only the profile pictures of
coauthors are shown, and the lead author's identity is suffixed with a
"+ N" to indicate co-authors.

in larger views of a commit, such as the commit view, the authors and
the committer are explicitly laid out, DIDs are resolved where possible
and shown alongside profile pictures.

Signed-off-by: oppiliappan <me@oppi.li>

authored by

oppiliappan and committed by
Tangled
fedd4bba 4d71c200

+116 -52
+1 -1
appview/pages/funcmap.go
··· 162 162 } 163 163 return pairs, nil 164 164 }, 165 - "append": func(s []string, values ...string) []string { 165 + "append": func(s []any, values ...any) []any { 166 166 s = append(s, values...) 167 167 return s 168 168 },
+34 -9
appview/pages/templates/repo/commit.html
··· 25 25 </div> 26 26 27 27 <div class="flex flex-wrap items-center space-x-2"> 28 - <p class="flex flex-wrap items-center gap-2 text-sm text-gray-500 dark:text-gray-300"> 29 - {{ $did := index $.EmailToDid $commit.Author.Email }} 30 - 31 - {{ if $did }} 32 - {{ template "user/fragments/picHandleLink" $did }} 33 - {{ else }} 34 - <a href="mailto:{{ $commit.Author.Email }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ $commit.Author.Name }}</a> 35 - {{ end }} 28 + <p class="flex flex-wrap items-center gap-1 text-sm text-gray-500 dark:text-gray-300"> 29 + {{ template "attribution" . }} 36 30 37 31 <span class="px-1 select-none before:content-['\00B7']"></span> 38 - {{ template "repo/fragments/time" $commit.Committer.When }} 32 + {{ template "repo/fragments/time" $commit.Committer.When }} 39 33 <span class="px-1 select-none before:content-['\00B7']"></span> 40 34 41 35 <a href="/{{ $repo }}/commit/{{ $commit.This }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ slice $commit.This 0 8 }}</a> ··· 72 78 73 79 </section> 74 80 {{end}} 81 + 82 + {{ define "attribution" }} 83 + {{ $commit := .Diff.Commit }} 84 + {{ $showCommitter := true }} 85 + {{ if eq $commit.Author.Email $commit.Committer.Email }} 86 + {{ $showCommitter = false }} 87 + {{ end }} 88 + 89 + {{ if $showCommitter }} 90 + authored by {{ template "attributedUser" (list $commit.Author.Email $commit.Author.Name $.EmailToDid) }} 91 + {{ range $commit.CoAuthors }} 92 + {{ template "attributedUser" (list .Email .Name $.EmailToDid) }} 93 + {{ end }} 94 + and committed by {{ template "attributedUser" (list $commit.Committer.Email $commit.Committer.Name $.EmailToDid) }} 95 + {{ else }} 96 + {{ template "attributedUser" (list $commit.Author.Email $commit.Author.Name $.EmailToDid )}} 97 + {{ end }} 98 + {{ end }} 99 + 100 + {{ define "attributedUser" }} 101 + {{ $email := index . 0 }} 102 + {{ $name := index . 1 }} 103 + {{ $map := index . 2 }} 104 + {{ $did := index $map $email }} 105 + 106 + {{ if $did }} 107 + {{ template "user/fragments/picHandleLink" $did }} 108 + {{ else }} 109 + <a href="mailto:{{ $email }}" class="no-underline hover:underline text-gray-500 dark:text-gray-300">{{ $name }}</a> 110 + {{ end }} 111 + {{ end }} 75 112 76 113 {{ define "topbarLayout" }} 77 114 <header class="col-span-full" style="z-index: 20;">
+30 -8
appview/pages/templates/repo/index.html
··· 14 14 {{ end }} 15 15 <div class="flex items-center justify-between pb-5"> 16 16 {{ block "branchSelector" . }}{{ end }} 17 - <div class="flex md:hidden items-center gap-2"> 17 + <div class="flex md:hidden items-center gap-3"> 18 18 <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="inline-flex items-center text-sm gap-1 font-bold"> 19 19 {{ i "git-commit-horizontal" "w-4" "h-4" }} {{ .TotalCommits }} 20 20 </a> ··· 66 66 67 67 {{ define "branchSelector" }} 68 68 <div class="flex gap-2 items-center justify-between w-full"> 69 - <div class="flex gap-2 items-center"> 69 + <div class="flex gap-2 items-stretch"> 70 70 <select 71 71 onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + encodeURIComponent(this.value)" 72 72 class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700" ··· 228 228 <span 229 229 class="mx-1 before:content-['·'] before:select-none" 230 230 ></span> 231 - <span> 232 - {{ $did := index $.EmailToDid .Author.Email }} 233 - <a href="{{ if $did }}/{{ resolve $did }}{{ else }}mailto:{{ .Author.Email }}{{ end }}" 234 - class="text-gray-500 dark:text-gray-400 no-underline hover:underline" 235 - >{{ if $did }}{{ template "user/fragments/picHandleLink" $did }}{{ else }}{{ .Author.Name }}{{ end }}</a> 236 - </span> 231 + {{ template "attribution" (list . $.EmailToDid) }} 237 232 <div class="inline-block px-1 select-none after:content-['·']"></div> 238 233 {{ template "repo/fragments/time" .Committer.When }} 239 234 ··· 254 259 {{ end }} 255 260 </div> 256 261 </div> 262 + {{ end }} 263 + 264 + {{ define "attribution" }} 265 + {{ $commit := index . 0 }} 266 + {{ $map := index . 1 }} 267 + <span class="flex items-center"> 268 + {{ $author := index $map $commit.Author.Email }} 269 + {{ $coauthors := $commit.CoAuthors }} 270 + {{ $all := list }} 271 + 272 + {{ if $author }} 273 + {{ $all = append $all $author }} 274 + {{ end }} 275 + {{ range $coauthors }} 276 + {{ $co := index $map .Email }} 277 + {{ if $co }} 278 + {{ $all = append $all $co }} 279 + {{ end }} 280 + {{ end }} 281 + 282 + {{ template "fragments/tinyAvatarList" (dict "all" $all "classes" "size-6") }} 283 + <a href="{{ if $author }}/{{ $author }}{{ else }}mailto:{{ $commit.Author.Email }}{{ end }}" 284 + class="no-underline hover:underline"> 285 + {{ if $author }}{{ resolve $author }}{{ else }}{{ $commit.Author.Name }}{{ end }} 286 + {{ if $coauthors }} +{{ length $coauthors }}{{ end }} 287 + </a> 288 + </span> 257 289 {{ end }} 258 290 259 291 {{ define "branchList" }}
+40 -23
appview/pages/templates/repo/log.html
··· 17 17 <div class="hidden md:flex md:flex-col divide-y divide-gray-200 dark:divide-gray-700"> 18 18 {{ $grid := "grid grid-cols-14 gap-4" }} 19 19 <div class="{{ $grid }}"> 20 - <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-2">Author</div> 20 + <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-3">Author</div> 21 21 <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-3">Commit</div> 22 22 <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-6">Message</div> 23 - <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-1"></div> 24 23 <div class="py-2 text-sm text-left text-gray-700 dark:text-gray-300 uppercase font-bold col-span-2 justify-self-end">Date</div> 25 24 </div> 26 25 {{ range $index, $commit := .Commits }} 27 26 {{ $messageParts := splitN $commit.Message "\n\n" 2 }} 28 27 <div class="{{ $grid }} py-3"> 29 - <div class="align-top truncate col-span-2"> 30 - {{ $did := index $.EmailToDid $commit.Author.Email }} 31 - {{ if $did }} 32 - {{ template "user/fragments/picHandleLink" $did }} 33 - {{ else }} 34 - <a href="mailto:{{ $commit.Author.Email }}" class="text-gray-700 dark:text-gray-300 no-underline hover:underline">{{ $commit.Author.Name }}</a> 35 - {{ end }} 28 + <div class="align-top col-span-3"> 29 + {{ template "attribution" (list $commit $.EmailToDid) }} 36 30 </div> 37 31 <div class="align-top font-mono flex items-start col-span-3"> 38 32 {{ $verified := $.VerifiedCommits.IsVerified $commit.Hash.String }} ··· 55 61 <div class="align-top col-span-6"> 56 62 <div> 57 63 <a href="/{{ $.RepoInfo.FullName }}/commit/{{ $commit.Hash.String }}" class="dark:text-white no-underline hover:underline">{{ index $messageParts 0 }}</a> 64 + 58 65 {{ if gt (len $messageParts) 1 }} 59 66 <button class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 dark:bg-gray-700 dark:hover:bg-gray-600 rounded" hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')">{{ i "ellipsis" "w-3 h-3" }}</button> 60 67 {{ end }} ··· 67 72 </span> 68 73 {{ end }} 69 74 {{ end }} 75 + 76 + <!-- ci status --> 77 + <span class="text-xs"> 78 + {{ $pipeline := index $.Pipelines .Hash.String }} 79 + {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 80 + {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $pipeline "RepoInfo" $.RepoInfo) }} 81 + {{ end }} 82 + </span> 70 83 </div> 71 84 72 85 {{ if gt (len $messageParts) 1 }} 73 86 <p class="hidden mt-1 text-sm text-gray-600 dark:text-gray-400">{{ nl2br (index $messageParts 1) }}</p> 74 87 {{ end }} 75 - </div> 76 - <div class="align-top col-span-1"> 77 - <!-- ci status --> 78 - {{ $pipeline := index $.Pipelines .Hash.String }} 79 - {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }} 80 - {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "Pipeline" $pipeline "RepoInfo" $.RepoInfo) }} 81 - {{ end }} 82 88 </div> 83 89 <div class="align-top justify-self-end text-gray-500 dark:text-gray-400 col-span-2">{{ template "repo/fragments/shortTimeAgo" $commit.Committer.When }}</div> 84 90 </div> ··· 148 152 </a> 149 153 </span> 150 154 <span class="mx-2 before:content-['·'] before:select-none"></span> 151 - <span> 152 - {{ $did := index $.EmailToDid $commit.Author.Email }} 153 - <a href="{{ if $did }}/{{ $did }}{{ else }}mailto:{{ $commit.Author.Email }}{{ end }}" 154 - class="text-gray-500 dark:text-gray-400 no-underline hover:underline"> 155 - {{ if $did }}{{ template "user/fragments/picHandleLink" $did }}{{ else }}{{ $commit.Author.Name }}{{ end }} 156 - </a> 157 - </span> 155 + {{ template "attribution" (list $commit $.EmailToDid) }} 158 156 <div class="inline-block px-1 select-none after:content-['·']"></div> 159 157 <span>{{ template "repo/fragments/shortTime" $commit.Committer.When }}</span> 160 158 ··· 166 176 </div> 167 177 </section> 168 178 179 + {{ end }} 180 + 181 + {{ define "attribution" }} 182 + {{ $commit := index . 0 }} 183 + {{ $map := index . 1 }} 184 + <span class="flex items-center gap-1"> 185 + {{ $author := index $map $commit.Author.Email }} 186 + {{ $coauthors := $commit.CoAuthors }} 187 + {{ $all := list }} 188 + 189 + {{ if $author }} 190 + {{ $all = append $all $author }} 191 + {{ end }} 192 + {{ range $coauthors }} 193 + {{ $co := index $map .Email }} 194 + {{ if $co }} 195 + {{ $all = append $all $co }} 196 + {{ end }} 197 + {{ end }} 198 + 199 + {{ template "fragments/tinyAvatarList" (dict "all" $all "classes" "size-6") }} 200 + <a href="{{ if $author }}/{{ $author }}{{ else }}mailto:{{ $commit.Author.Email }}{{ end }}" 201 + class="no-underline hover:underline"> 202 + {{ if $author }}{{ resolve $author }}{{ else }}{{ $commit.Author.Name }}{{ end }} 203 + {{ if $coauthors }} +{{ length $coauthors }}{{ end }} 204 + </a> 205 + </span> 169 206 {{ end }} 170 207 171 208 {{ define "repoAfter" }}
+10 -10
appview/repo/repo_util.go
··· 1 1 package repo 2 2 3 3 import ( 4 + "maps" 4 5 "slices" 5 6 "sort" 6 7 "strings" ··· 44 43 func uniqueEmails(commits []types.Commit) []string { 45 44 emails := make(map[string]struct{}) 46 45 for _, commit := range commits { 47 - if commit.Author.Email != "" { 48 - emails[commit.Author.Email] = struct{}{} 49 - } 50 - if commit.Committer.Email != "" { 51 - emails[commit.Committer.Email] = struct{}{} 46 + emails[commit.Author.Email] = struct{}{} 47 + emails[commit.Committer.Email] = struct{}{} 48 + for _, c := range commit.CoAuthors() { 49 + emails[c.Email] = struct{}{} 52 50 } 53 51 } 54 - var uniqueEmails []string 55 - for email := range emails { 56 - uniqueEmails = append(uniqueEmails, email) 57 - } 58 - return uniqueEmails 52 + 53 + // delete empty emails if any, from the set 54 + delete(emails, "") 55 + 56 + return slices.Collect(maps.Keys(emails)) 59 57 } 60 58 61 59 func balanceIndexItems(commitCount, branchCount, tagCount, fileCount int) (commitsTrunc int, branchesTrunc int, tagsTrunc int) {
+1 -1
types/commit.go
··· 172 172 coAuthorRegex = regexp.MustCompile(`(?im)^Co-authored-by:\s*(.+?)\s*<([^>]+)>`) 173 173 ) 174 174 175 - func (commit *Commit) CoAuthors() []object.Signature { 175 + func (commit Commit) CoAuthors() []object.Signature { 176 176 var coAuthors []object.Signature 177 177 178 178 matches := coAuthorRegex.FindAllStringSubmatch(commit.Message, -1)