forked from tangled.org/core
Monorepo for Tangled

appview: add fork button

authored by anirudh.fi and committed by oppi.li 1428c3be 4fac8249

Changed files
+64 -47
appview
db
pages
templates
fragments
layouts
state
+6 -5
appview/db/profile.go
··· 1 package db 2 3 import ( 4 "sort" 5 "time" 6 ) ··· 19 20 pulls, err := GetPullsByOwnerDid(e, forDid) 21 if err != nil { 22 - return timeline, err 23 } 24 25 for _, pull := range pulls { 26 repo, err := GetRepoByAtUri(e, string(pull.RepoAt)) 27 if err != nil { 28 - return timeline, err 29 } 30 31 timeline = append(timeline, ProfileTimelineEvent{ ··· 38 39 issues, err := GetIssuesByOwnerDid(e, forDid) 40 if err != nil { 41 - return timeline, err 42 } 43 44 for _, issue := range issues { 45 repo, err := GetRepoByAtUri(e, string(issue.RepoAt)) 46 if err != nil { 47 - return timeline, err 48 } 49 50 timeline = append(timeline, ProfileTimelineEvent{ ··· 57 58 repos, err := GetAllReposByDid(e, forDid) 59 if err != nil { 60 - return timeline, err 61 } 62 63 for _, repo := range repos {
··· 1 package db 2 3 import ( 4 + "fmt" 5 "sort" 6 "time" 7 ) ··· 20 21 pulls, err := GetPullsByOwnerDid(e, forDid) 22 if err != nil { 23 + return timeline, fmt.Errorf("error getting pulls by owner did: %w", err) 24 } 25 26 for _, pull := range pulls { 27 repo, err := GetRepoByAtUri(e, string(pull.RepoAt)) 28 if err != nil { 29 + return timeline, fmt.Errorf("error getting repo by at uri: %w", err) 30 } 31 32 timeline = append(timeline, ProfileTimelineEvent{ ··· 39 40 issues, err := GetIssuesByOwnerDid(e, forDid) 41 if err != nil { 42 + return timeline, fmt.Errorf("error getting issues by owner did: %w", err) 43 } 44 45 for _, issue := range issues { 46 repo, err := GetRepoByAtUri(e, string(issue.RepoAt)) 47 if err != nil { 48 + return timeline, fmt.Errorf("error getting repo by at uri: %w", err) 49 } 50 51 timeline = append(timeline, ProfileTimelineEvent{ ··· 58 59 repos, err := GetAllReposByDid(e, forDid) 60 if err != nil { 61 + return timeline, fmt.Errorf("error getting all repos by did: %w", err) 62 } 63 64 for _, repo := range repos {
+5 -4
appview/db/repos.go
··· 88 var repoStats RepoStats 89 var createdAt string 90 var nullableDescription sql.NullString 91 92 - err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount) 93 if err != nil { 94 return nil, err 95 } ··· 179 } 180 181 func GetRepoSource(e Execer, repoAt syntax.ATURI) (string, error) { 182 - var source string 183 - err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&source) 184 if err != nil { 185 return "", err 186 } 187 - return source, nil 188 } 189 190 func AddCollaborator(e Execer, collaborator, repoOwnerDid, repoName, repoKnot string) error {
··· 88 var repoStats RepoStats 89 var createdAt string 90 var nullableDescription sql.NullString 91 + var nullableSource sql.NullString 92 93 + err := rows.Scan(&repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &nullableDescription, &createdAt, &repoStats.StarCount, &nullableSource) 94 if err != nil { 95 return nil, err 96 } ··· 180 } 181 182 func GetRepoSource(e Execer, repoAt syntax.ATURI) (string, error) { 183 + var nullableSource sql.NullString 184 + err := e.QueryRow(`select source from repos where at_uri = ?`, repoAt).Scan(&nullableSource) 185 if err != nil { 186 return "", err 187 } 188 + return nullableSource.String, nil 189 } 190 191 func AddCollaborator(e Execer, collaborator, repoOwnerDid, repoName, repoKnot string) error {
+3 -3
appview/pages/pages.go
··· 199 return p.executePlain("fragments/follow", w, params) 200 } 201 202 - type StarFragmentParams struct { 203 IsStarred bool 204 RepoAt syntax.ATURI 205 Stats db.RepoStats 206 } 207 208 - func (p *Pages) StarFragment(w io.Writer, params StarFragmentParams) error { 209 - return p.executePlain("fragments/star", w, params) 210 } 211 212 type RepoDescriptionParams struct {
··· 199 return p.executePlain("fragments/follow", w, params) 200 } 201 202 + type RepoActionsFragmentParams struct { 203 IsStarred bool 204 RepoAt syntax.ATURI 205 Stats db.RepoStats 206 } 207 208 + func (p *Pages) RepoActionsFragment(w io.Writer, params RepoActionsFragmentParams) error { 209 + return p.executePlain("fragments/repoActions", w, params) 210 } 211 212 type RepoDescriptionParams struct {
+8 -2
appview/pages/templates/fragments/star.html appview/pages/templates/fragments/repoActions.html
··· 1 - {{ define "fragments/star" }} 2 <button id="starBtn" 3 - class="text-sm disabled:opacity-50 disabled:cursor-not-allowed" 4 5 {{ if .IsStarred }} 6 hx-delete="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}" ··· 24 </span> 25 </div> 26 </button> 27 {{ end }} 28
··· 1 + {{ define "fragments/repoActions" }} 2 + <div class="flex items-center"> 3 <button id="starBtn" 4 + class="btn disabled:opacity-50 disabled:cursor-not-allowed" 5 6 {{ if .IsStarred }} 7 hx-delete="/star?subject={{.RepoAt}}&countHint={{.Stats.StarCount}}" ··· 25 </span> 26 </div> 27 </button> 28 + <a class="btn no-underline hover:no-underline flex items-center" href="/{{ .FullName }}/fork"> 29 + {{ i "git-fork" "w-3 h-3 mr-1"}} 30 + fork 31 + </a> 32 + </div> 33 {{ end }} 34
+26 -22
appview/pages/templates/layouts/repobase.html
··· 1 {{ define "title" }}{{ .RepoInfo.FullName }}{{ end }} 2 3 {{ define "content" }} 4 - <section id="repo-header" class="mb-4 py-2 px-6 dark:text-white"> 5 - {{ if .RepoInfo.Source }} 6 - <p class="text-sm"> 7 - <div class="flex items-center"> 8 - {{ i "git-fork" "w-3 h-3 mr-1"}} 9 - forked from 10 - {{ $sourceOwner := didOrHandle .RepoInfo.Source.Did .RepoInfo.SourceHandle }} 11 - <a class="ml-1 underline" href="/{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}">{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}</a> 12 - </div> 13 - </p> 14 - {{ end }} 15 - <p class="text-lg"> 16 - <a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a> 17 - <span class="select-none">/</span> 18 - <a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a> 19 - <span class="ml-3"> 20 - {{ template "fragments/star" .RepoInfo }} 21 - </span> 22 - </p> 23 - {{ template "fragments/repoDescription" . }} 24 - </section> 25 <section class="min-h-screen flex flex-col drop-shadow-sm"> 26 <nav class="w-full pl-4 overflow-auto"> 27 <div class="flex z-60"> ··· 46 {{ end }} 47 " 48 > 49 - {{ $key }} 50 {{ if not (isNil $meta) }} 51 <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-sm">{{ $meta }}</span> 52 {{ end }}
··· 1 {{ define "title" }}{{ .RepoInfo.FullName }}{{ end }} 2 3 {{ define "content" }} 4 + <section id="repo-header" class="mb-4 py-2 px-6 dark:text-white"> 5 + {{ if .RepoInfo.Source }} 6 + <p class="text-sm"> 7 + <div class="flex items-center"> 8 + {{ i "git-fork" "w-3 h-3 mr-1"}} 9 + forked from 10 + {{ $sourceOwner := didOrHandle .RepoInfo.Source.Did .RepoInfo.SourceHandle }} 11 + <a class="ml-1 underline" href="/{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}">{{ $sourceOwner }}/{{ .RepoInfo.Source.Name }}</a> 12 + </div> 13 + </p> 14 + {{ end }} 15 + <div class="text-lg flex items-center justify-between"> 16 + <div> 17 + <a href="/{{ .RepoInfo.OwnerWithAt }}">{{ .RepoInfo.OwnerWithAt }}</a> 18 + <span class="select-none">/</span> 19 + <a href="/{{ .RepoInfo.FullName }}" class="font-bold">{{ .RepoInfo.Name }}</a> 20 + </div> 21 + <div class="flex items-center"> 22 + <span class="mr-3"> 23 + {{ template "fragments/repoActions" .RepoInfo }} 24 + </span> 25 + </div> 26 + </div> 27 + {{ template "fragments/repoDescription" . }} 28 + </section> 29 <section class="min-h-screen flex flex-col drop-shadow-sm"> 30 <nav class="w-full pl-4 overflow-auto"> 31 <div class="flex z-60"> ··· 50 {{ end }} 51 " 52 > 53 + {{ $key }} 54 {{ if not (isNil $meta) }} 55 <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-sm">{{ $meta }}</span> 56 {{ end }}
+14 -9
appview/state/repo.go
··· 807 if errors.Is(err, sql.ErrNoRows) { 808 source = "" 809 } else if err != nil { 810 - log.Println("failed to get repo source for ", f.RepoAt) 811 } 812 813 var sourceRepo *db.Repo ··· 818 } 819 } 820 821 - knot := f.Knot 822 - if knot == "knot1.tangled.sh" { 823 - knot = "tangled.sh" 824 - } 825 - 826 var sourceHandle *identity.Identity 827 if sourceRepo != nil { 828 sourceHandle, err = s.resolver.ResolveIdent(context.Background(), sourceRepo.Did) ··· 831 } 832 } 833 834 - return pages.RepoInfo{ 835 OwnerDid: f.OwnerDid(), 836 OwnerHandle: f.OwnerHandle(), 837 Name: f.RepoName, ··· 845 IssueCount: issueCount, 846 PullCount: pullCount, 847 }, 848 - Source: sourceRepo, 849 - SourceHandle: sourceHandle.Handle.String(), 850 } 851 } 852 853 func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
··· 807 if errors.Is(err, sql.ErrNoRows) { 808 source = "" 809 } else if err != nil { 810 + log.Println("failed to get repo source for ", f.RepoAt, err) 811 } 812 813 var sourceRepo *db.Repo ··· 818 } 819 } 820 821 var sourceHandle *identity.Identity 822 if sourceRepo != nil { 823 sourceHandle, err = s.resolver.ResolveIdent(context.Background(), sourceRepo.Did) ··· 826 } 827 } 828 829 + knot := f.Knot 830 + if knot == "knot1.tangled.sh" { 831 + knot = "tangled.sh" 832 + } 833 + 834 + repoInfo := pages.RepoInfo{ 835 OwnerDid: f.OwnerDid(), 836 OwnerHandle: f.OwnerHandle(), 837 Name: f.RepoName, ··· 845 IssueCount: issueCount, 846 PullCount: pullCount, 847 }, 848 + } 849 + 850 + if sourceRepo != nil { 851 + repoInfo.Source = sourceRepo 852 + repoInfo.SourceHandle = sourceHandle.Handle.String() 853 } 854 + 855 + return repoInfo 856 } 857 858 func (s *State) RepoSingleIssue(w http.ResponseWriter, r *http.Request) {
+2 -2
appview/state/star.go
··· 62 63 log.Println("created atproto record: ", resp.Uri) 64 65 - s.pages.StarFragment(w, pages.StarFragmentParams{ 66 IsStarred: true, 67 RepoAt: subjectUri, 68 Stats: db.RepoStats{ ··· 101 log.Println("failed to get star count for ", subjectUri) 102 } 103 104 - s.pages.StarFragment(w, pages.StarFragmentParams{ 105 IsStarred: false, 106 RepoAt: subjectUri, 107 Stats: db.RepoStats{
··· 62 63 log.Println("created atproto record: ", resp.Uri) 64 65 + s.pages.RepoActionsFragment(w, pages.RepoActionsFragmentParams{ 66 IsStarred: true, 67 RepoAt: subjectUri, 68 Stats: db.RepoStats{ ··· 101 log.Println("failed to get star count for ", subjectUri) 102 } 103 104 + s.pages.RepoActionsFragment(w, pages.RepoActionsFragmentParams{ 105 IsStarred: false, 106 RepoAt: subjectUri, 107 Stats: db.RepoStats{