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 }
44
45 if r.Roles.SettingsAllowed() {
46 tabs = append(tabs, []string{"settings", "/settings", "cog"})
47 }
48
49 return tabs
50}
51
52type RepoInfo struct {
53 Name string
54 OwnerDid string
55 OwnerHandle string
56 Description string
57 Knot string
58 RepoAt syntax.ATURI
59 IsStarred bool
60 Stats db.RepoStats
61 Roles RolesInRepo
62 Source *db.Repo
63 SourceHandle string
64 Ref string
65 DisableFork bool
66}
67
68// each tab on a repo could have some metadata:
69//
70// issues -> number of open issues etc.
71// settings -> a warning icon to setup branch protection? idk
72//
73// we gather these bits of info here, because go templates
74// are difficult to program in
75func (r RepoInfo) TabMetadata() map[string]any {
76 meta := make(map[string]any)
77
78 if r.Stats.PullCount.Open > 0 {
79 meta["pulls"] = r.Stats.PullCount.Open
80 }
81
82 if r.Stats.IssueCount.Open > 0 {
83 meta["issues"] = r.Stats.IssueCount.Open
84 }
85
86 // more stuff?
87
88 return meta
89}
90
91type RolesInRepo struct {
92 Roles []string
93}
94
95func (r RolesInRepo) SettingsAllowed() bool {
96 return slices.Contains(r.Roles, "repo:settings")
97}
98
99func (r RolesInRepo) CollaboratorInviteAllowed() bool {
100 return slices.Contains(r.Roles, "repo:invite")
101}
102
103func (r RolesInRepo) RepoDeleteAllowed() bool {
104 return slices.Contains(r.Roles, "repo:delete")
105}
106
107func (r RolesInRepo) IsOwner() bool {
108 return slices.Contains(r.Roles, "repo:owner")
109}
110
111func (r RolesInRepo) IsCollaborator() bool {
112 return slices.Contains(r.Roles, "repo:collaborator")
113}
114
115func (r RolesInRepo) IsPushAllowed() bool {
116 return slices.Contains(r.Roles, "repo:push")
117}