1package repoinfo
2
3import (
4 "fmt"
5 "path"
6 "slices"
7 "strings"
8
9 "github.com/bluesky-social/indigo/atproto/syntax"
10 "tangled.sh/tangled.sh/core/appview/db"
11 "tangled.sh/tangled.sh/core/appview/state/userutil"
12)
13
14func (r RepoInfo) OwnerWithAt() string {
15 if r.OwnerHandle != "" {
16 return fmt.Sprintf("@%s", r.OwnerHandle)
17 } else {
18 return r.OwnerDid
19 }
20}
21
22func (r RepoInfo) FullName() string {
23 return path.Join(r.OwnerWithAt(), r.Name)
24}
25
26func (r RepoInfo) OwnerWithoutAt() string {
27 if strings.HasPrefix(r.OwnerWithAt(), "@") {
28 return strings.TrimPrefix(r.OwnerWithAt(), "@")
29 } else {
30 return userutil.FlattenDid(r.OwnerDid)
31 }
32}
33
34func (r RepoInfo) FullNameWithoutAt() string {
35 return path.Join(r.OwnerWithoutAt(), r.Name)
36}
37
38func (r RepoInfo) GetTabs() [][]string {
39 tabs := [][]string{
40 {"overview", "/", "square-chart-gantt"},
41 {"issues", "/issues", "circle-dot"},
42 {"pulls", "/pulls", "git-pull-request"},
43 {"pipelines", "/pipelines", "layers-2"},
44 }
45
46 if r.Roles.SettingsAllowed() {
47 tabs = append(tabs, []string{"settings", "/settings", "cog"})
48 }
49
50 return tabs
51}
52
53type RepoInfo struct {
54 Name string
55 OwnerDid string
56 OwnerHandle string
57 Description string
58 Knot string
59 Spindle string
60 RepoAt syntax.ATURI
61 IsStarred bool
62 Stats db.RepoStats
63 Roles RolesInRepo
64 Source *db.Repo
65 SourceHandle string
66 Ref string
67 DisableFork bool
68 CurrentDir string
69}
70
71// each tab on a repo could have some metadata:
72//
73// issues -> number of open issues etc.
74// settings -> a warning icon to setup branch protection? idk
75//
76// we gather these bits of info here, because go templates
77// are difficult to program in
78func (r RepoInfo) TabMetadata() map[string]any {
79 meta := make(map[string]any)
80
81 if r.Stats.PullCount.Open > 0 {
82 meta["pulls"] = r.Stats.PullCount.Open
83 }
84
85 if r.Stats.IssueCount.Open > 0 {
86 meta["issues"] = r.Stats.IssueCount.Open
87 }
88
89 // more stuff?
90
91 return meta
92}
93
94type RolesInRepo struct {
95 Roles []string
96}
97
98func (r RolesInRepo) SettingsAllowed() bool {
99 return slices.Contains(r.Roles, "repo:settings")
100}
101
102func (r RolesInRepo) CollaboratorInviteAllowed() bool {
103 return slices.Contains(r.Roles, "repo:invite")
104}
105
106func (r RolesInRepo) RepoDeleteAllowed() bool {
107 return slices.Contains(r.Roles, "repo:delete")
108}
109
110func (r RolesInRepo) IsOwner() bool {
111 return slices.Contains(r.Roles, "repo:owner")
112}
113
114func (r RolesInRepo) IsCollaborator() bool {
115 return slices.Contains(r.Roles, "repo:collaborator")
116}
117
118func (r RolesInRepo) IsPushAllowed() bool {
119 return slices.Contains(r.Roles, "repo:push")
120}