fix first commit duplication in log view
ADDED
appview/pages/funcMap.go
ADDED
appview/pages/funcMap.go
@@ -0,0 +1,107 @@+package pages++import (+ "fmt"+ "html"+ "html/template"+ "reflect"+ "strings"++ "github.com/dustin/go-humanize"+)++func funcMap() template.FuncMap {+ return template.FuncMap{+ "split": func(s string) []string {+ return strings.Split(s, "\n")+ },+ "splitOn": func(s, sep string) []string {+ return strings.Split(s, sep)+ },+ "add": func(a, b int) int {+ return a + b+ },+ "sub": func(a, b int) int {+ return a - b+ },+ "cond": func(cond interface{}, a, b string) string {+ if cond == nil {+ return b+ }++ if boolean, ok := cond.(bool); boolean && ok {+ return a+ }++ return b+ },+ "didOrHandle": func(did, handle string) string {+ if handle != "" {+ return fmt.Sprintf("@%s", handle)+ } else {+ return did+ }+ },+ "assoc": func(values ...string) ([][]string, error) {+ if len(values)%2 != 0 {+ return nil, fmt.Errorf("invalid assoc call, must have an even number of arguments")+ }+ pairs := make([][]string, 0)+ for i := 0; i < len(values); i += 2 {+ pairs = append(pairs, []string{values[i], values[i+1]})+ }+ return pairs, nil+ },+ "append": func(s []string, values ...string) []string {+ s = append(s, values...)+ return s+ },+ "timeFmt": humanize.Time,+ "byteFmt": humanize.Bytes,+ "length": func(slice interface{}) int {+ v := reflect.ValueOf(slice)+ if v.Kind() == reflect.Slice || v.Kind() == reflect.Array {+ return v.Len()+ }+ return 0+ },+ "splitN": func(s, sep string, n int) []string {+ return strings.SplitN(s, sep, n)+ },+ "escapeHtml": func(s string) template.HTML {+ if s == "" {+ return template.HTML("<br>")+ }+ return template.HTML(s)+ },+ "unescapeHtml": func(s string) string {+ return html.UnescapeString(s)+ },+ "nl2br": func(text string) template.HTML {+ return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1))+ },+ "unwrapText": func(text string) string {+ paragraphs := strings.Split(text, "\n\n")++ for i, p := range paragraphs {+ lines := strings.Split(p, "\n")+ paragraphs[i] = strings.Join(lines, " ")+ }++ return strings.Join(paragraphs, "\n\n")+ },+ "sequence": func(n int) []struct{} {+ return make([]struct{}, n)+ },+ "subslice": func(slice interface{}, start, end int) interface{} {+ v := reflect.ValueOf(slice)+ if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {+ return nil+ }+ if start < 0 || start > v.Len() || end > v.Len() || start > end {+ return nil+ }+ return v.Slice(start, end).Interface()+ },+ }+}
MODIFIED
appview/pages/pages.go
MODIFIED
appview/pages/pages.go
@@ -4,7 +4,6 @@ import ("bytes""embed""fmt"- "html""html/template""io""io/fs"@@ -18,7 +17,6 @@ "github.com/alecthomas/chroma/v2"chromahtml "github.com/alecthomas/chroma/v2/formatters/html""github.com/alecthomas/chroma/v2/lexers""github.com/alecthomas/chroma/v2/styles"- "github.com/dustin/go-humanize""github.com/sotangled/tangled/appview/auth""github.com/sotangled/tangled/appview/db""github.com/sotangled/tangled/types"@@ -29,88 +27,6 @@ var files embed.FStype Pages struct {t map[string]*template.Template-}--func funcMap() template.FuncMap {- return template.FuncMap{- "split": func(s string) []string {- return strings.Split(s, "\n")- },- "splitOn": func(s, sep string) []string {- return strings.Split(s, sep)- },- "add": func(a, b int) int {- return a + b- },- "sub": func(a, b int) int {- return a - b- },- "cond": func(cond interface{}, a, b string) string {- if cond == nil {- return b- }-- if boolean, ok := cond.(bool); boolean && ok {- return a- }-- return b- },- "didOrHandle": func(did, handle string) string {- if handle != "" {- return fmt.Sprintf("@%s", handle)- } else {- return did- }- },- "assoc": func(values ...string) ([][]string, error) {- if len(values)%2 != 0 {- return nil, fmt.Errorf("invalid assoc call, must have an even number of arguments")- }- pairs := make([][]string, 0)- for i := 0; i < len(values); i += 2 {- pairs = append(pairs, []string{values[i], values[i+1]})- }- return pairs, nil- },- "append": func(s []string, values ...string) []string {- s = append(s, values...)- return s- },- "timeFmt": humanize.Time,- "byteFmt": humanize.Bytes,- "length": func(v []string) int {- return len(v)- },- "splitN": func(s, sep string, n int) []string {- return strings.SplitN(s, sep, n)- },- "escapeHtml": func(s string) template.HTML {- if s == "" {- return template.HTML("<br>")- }- return template.HTML(s)- },- "unescapeHtml": func(s string) string {- return html.UnescapeString(s)- },- "nl2br": func(text string) template.HTML {- return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1))- },- "unwrapText": func(text string) string {- paragraphs := strings.Split(text, "\n\n")-- for i, p := range paragraphs {- lines := strings.Split(p, "\n")- paragraphs[i] = strings.Join(lines, " ")- }-- return strings.Join(paragraphs, "\n\n")- },- "sequence": func(n int) []struct{} {- return make([]struct{}, n)- },- }}func NewPages() *Pages {
@@ -2,10 +2,10 @@ {{ define "title" }}{{ .RepoInfo.FullName }}{{ end }}{{ define "content" }}<section id="repo-header" class="mb-4 p-2">- <p class="text-lg font-bold">+ <p class="text-lg"><a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a><span class="select-none">/</span>- <a href="/{{ .RepoInfo.FullName }}">{{ .RepoInfo.Name }}</a>+ <a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a></p><span>{{ if .RepoInfo.Description }}
@@ -46,7 +46,7 @@ {{ if eq .TotalCommits 1 }}commit{{ else }}commits{{ end }}</a></div>- <div class="flex gap-4">+ <div class="flex gap-2"><div id="file-tree" class="w-3/5 pr-2 border-r border-gray-200">{{ $containerstyle := "py-1" }}{{ $linkstyle := "no-underline hover:underline" }}@@ -104,71 +104,65 @@ </div><div id="commit-log" class="flex-1">{{ range .Commits }}- <div class="flex flex-row items-center">- <i- class="w-5 h-5 text-gray-400 align-top"- data-lucide="git-commit-horizontal"- ></i>- <div class="relative px-4 py-4">- <div id="commit-message">- {{ $messageParts := splitN .Message "\n\n" 2 }}- <div class="text-base cursor-pointer">- <div>- <div>- <a- href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"- class="inline no-underline hover:underline"- >{{ index $messageParts 0 }}</a- >- {{ if gt (len $messageParts) 1 }}+ <div class="relative px-2 pb-8">+ <div id="commit-message">+ {{ $messageParts := splitN .Message "\n\n" 2 }}+ <div class="text-base cursor-pointer">+ <div>+ <div>+ <a+ href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"+ class="inline no-underline hover:underline"+ >{{ index $messageParts 0 }}</a+ >+ {{ if gt (len $messageParts) 1 }}- <button- class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded"- hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"- >- <i- class="w-3 h-3"- data-lucide="ellipsis"- ></i>- </button>- {{ end }}- </div>- {{ if gt (len $messageParts) 1 }}- <p- class="hidden mt-1 text-sm cursor-text pb-2"- >- {{ nl2br (unwrapText (index $messageParts 1)) }}- </p>- {{ end }}- </div>- </div>- </div>+ <button+ class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded"+ hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"+ >+ <i+ class="w-3 h-3"+ data-lucide="ellipsis"+ ></i>+ </button>+ {{ end }}+ </div>+ {{ if gt (len $messageParts) 1 }}+ <p+ class="hidden mt-1 text-sm cursor-text pb-2"+ >+ {{ nl2br (unwrapText (index $messageParts 1)) }}+ </p>+ {{ end }}+ </div>+ </div>+ </div>- <div class="text-xs text-gray-500">- <span class="font-mono">- <a- href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"- class="text-gray-500 no-underline hover:underline"- >{{ slice .Hash.String 0 8 }}</a- >- </span>- <span- class="mx-2 before:content-['·'] before:select-none"- ></span>- <span>- <a- href="mailto:{{ .Author.Email }}"- class="text-gray-500 no-underline hover:underline"- >{{ .Author.Name }}</a- >- </span>- <div- class="inline-block px-1 select-none after:content-['·']"- ></div>- <span>{{ timeFmt .Author.When }}</span>- </div>- </div>- </div>+ <div class="text-xs text-gray-500">+ <span class="font-mono">+ <a+ href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"+ class="text-gray-500 no-underline hover:underline"+ >{{ slice .Hash.String 0 8 }}</a+ >+ </span>+ <span+ class="mx-2 before:content-['·'] before:select-none"+ ></span>+ <span>+ <a+ href="mailto:{{ .Author.Email }}"+ class="text-gray-500 no-underline hover:underline"+ >{{ .Author.Name }}</a+ >+ </span>+ <div+ class="inline-block px-1 select-none after:content-['·']"+ ></div>+ <span>{{ timeFmt .Author.When }}</span>+ </div>+ </div>{{ end }}</div></div>
@@ -41,7 +41,9 @@ {{ define "repoAfter" }}<main><div id="commit-log" class="flex-1 relative"><div class="absolute left-8 top-0 bottom-0 w-px bg-gray-300"></div>- {{ range .Commits }}+ {{ $end := length .Commits }}+ {{ $commits := subslice .Commits 1 $end }}+ {{ range $commits }}<div class="flex flex-row justify-between items-center"><divclass="relative w-full px-4 py-4 mt-5 hover:bg-gray-50 rounded-sm bg-white"@@ -112,7 +114,7 @@ {{ $commits_len := len .Commits }}<div class="flex justify-end mt-4 gap-2">{{ if gt .Page 1 }}<a- class="btn flex items-center gap-2 no-underline"+ class="btn flex items-center gap-2 no-underline hover:no-underline"hx-boost="true"onclick="window.location.href = window.location.pathname + '?page={{ sub .Page 1 }}'">@@ -125,7 +127,7 @@ {{ end }}{{ if eq $commits_len 30 }}<a- class="btn flex items-center gap-2 no-underline"+ class="btn flex items-center gap-2 no-underline hover:no-underline"hx-boost="true"onclick="window.location.href = window.location.pathname + '?page={{ add .Page 1 }}'">
@@ -1,7 +1,7 @@{{ define "title" }}{{ or .UserHandle .UserDid }}{{ end }}{{ define "content" }}- <div class="flex ">+ <div class="flex"><h1 class="pb-1">{{ didOrHandle .UserDid .UserHandle }}</h1>@@ -26,7 +26,7 @@ <span>{{ .ProfileStats.Followers }} followers</span><div class="inline-block px-1 select-none after:content-['·']"></div><span>{{ .ProfileStats.Following }} following</span></div>- <p class="text-xs font-bold py-2">REPOS</p>+ <p class="text-sm font-bold py-2">REPOS</p><div id="repos" class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">{{ range .Repos }}<div@@ -49,7 +49,7 @@ {{ else }}<p>This user does not have any repos yet.</p>{{ end }}</div>- <p class="text-xs font-bold py-2">COLLABORATING ON</p>+ <p class="text-sm font-bold py-2">COLLABORATING ON</p><div id="collaborating" class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">{{ range .CollaboratingRepos }}<div
MODIFIED
appview/state/middleware.go
MODIFIED
appview/state/middleware.go
@@ -147,7 +147,6 @@func ResolveIdent(s *State) Middleware {return func(next http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {- start := time.Now()didOrHandle := chi.URLParam(req, "user")id, err := s.resolver.ResolveIdent(req.Context(), didOrHandle)@@ -160,8 +159,6 @@ }ctx := context.WithValue(req.Context(), "resolvedId", *id)- elapsed := time.Since(start)- log.Println("Execution time:", elapsed)next.ServeHTTP(w, req.WithContext(ctx))})}
MODIFIED
appview/state/repo.go
MODIFIED
appview/state/repo.go
@@ -207,6 +207,8 @@baseTreeLink := path.Join(f.OwnerDid(), f.RepoName, "tree", ref, treePath)baseBlobLink := path.Join(f.OwnerDid(), f.RepoName, "blob", ref, treePath)+ log.Println(result)+s.pages.RepoTree(w, pages.RepoTreeParams{LoggedInUser: user,BreadCrumbs: breadcrumbs,