+12
appview/pages/pages.go
+12
appview/pages/pages.go
···
865
Tags []*types.TagReference
866
Base string
867
Head string
868
869
Active string
870
}
···
872
func (p *Pages) RepoCompare(w io.Writer, params RepoCompareParams) error {
873
params.Active = "overview"
874
return p.executeRepo("repo/compare", w, params)
875
}
876
877
type RepoCompareDiffParams struct {
···
865
Tags []*types.TagReference
866
Base string
867
Head string
868
+
AllowPull bool
869
870
Active string
871
}
···
873
func (p *Pages) RepoCompare(w io.Writer, params RepoCompareParams) error {
874
params.Active = "overview"
875
return p.executeRepo("repo/compare", w, params)
876
+
}
877
+
878
+
type RepoCompareAllowPullParams struct {
879
+
LoggedInUser *oauth.User
880
+
RepoInfo repoinfo.RepoInfo
881
+
Base string
882
+
Head string
883
+
}
884
+
885
+
func (p *Pages) RepoCompareAllowPullFragment(w io.Writer, params RepoCompareAllowPullParams) error {
886
+
return p.executePlain("repo/fragments/compareAllowPull", w, params)
887
}
888
889
type RepoCompareDiffParams struct {
+18
-2
appview/pages/templates/repo/compare.html
+18
-2
appview/pages/templates/repo/compare.html
···
1
-
{{ define "title" }}new comparison{{ end }}
2
3
{{ define "repoContent" }}
4
<section>
···
104
</div>
105
</form>
106
</section>
107
-
<section class="hidden"></section>
108
109
<script>
110
var templatedBase = `{{ .Base }}`;
···
147
if (baseToUse && headToUse) {
148
const url = `/{{ .RepoInfo.FullName }}/compare/diff/${baseToUse}/${headToUse}`;
149
htmx.ajax('GET', url, { target: '#compare-diff' });
150
}
151
}
152
</script>
153
{{ end }}
154
155
{{ define "repoAfter" }}
···
1
+
{{ define "title" }}
2
+
{{ if and .Head .Base }}
3
+
comparing {{ .Base }} and
4
+
{{ .Head }}
5
+
{{ else }}
6
+
new comparison
7
+
{{ end }}
8
+
{{ end }}
9
10
{{ define "repoContent" }}
11
<section>
···
111
</div>
112
</form>
113
</section>
114
115
<script>
116
var templatedBase = `{{ .Base }}`;
···
153
if (baseToUse && headToUse) {
154
const url = `/{{ .RepoInfo.FullName }}/compare/diff/${baseToUse}/${headToUse}`;
155
htmx.ajax('GET', url, { target: '#compare-diff' });
156
+
document.title = `comparing ${baseToUse} and ${headToUse}`;
157
+
158
+
const allowPull = `{{ .AllowPull }}`
159
+
if (allowPull) {
160
+
htmx.ajax('GET',
161
+
`/{{ .RepoInfo.FullName }}/compare/allow-pull/${baseToUse}/${headToUse}`,
162
+
{ target: '#allow-pull'},
163
+
)
164
+
}
165
}
166
}
167
</script>
168
+
<section id="allow-pull" class="pt-4"></section>
169
{{ end }}
170
171
{{ define "repoAfter" }}
+24
appview/pages/templates/repo/fragments/compareAllowPull.html
+24
appview/pages/templates/repo/fragments/compareAllowPull.html
···
···
1
+
{{ define "repo/fragments/compareAllowPull" }}
2
+
<div class="flex items-baseline justify-normal gap-4">
3
+
<p>
4
+
This comparison can be turned into a pull request to be reviewed and
5
+
discussed.
6
+
</p>
7
+
8
+
{{ $newPullUrl := printf "/%s/pulls/new?strategy=branch&targetBranch=%s&sourceBranch=%s" .RepoInfo.FullName .Base .Head }}
9
+
10
+
11
+
<div class="flex justify-start items-center gap-2 mt-2">
12
+
<a
13
+
href="{{ $newPullUrl }}"
14
+
class="btn flex items-center gap-2 no-underline hover:no-underline"
15
+
>
16
+
{{ i "git-pull-request-create" "w-4 h-4" }}
17
+
create pull
18
+
<span id="create-pull-spinner" class="group">
19
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
20
+
</span>
21
+
</a>
22
+
</div>
23
+
</div>
24
+
{{ end }}
+27
appview/state/repo.go
+27
appview/state/repo.go
···
2110
}
2111
}
2112
2113
+
var allowPull bool = false
2114
+
if user != nil {
2115
+
if slices.ContainsFunc(branches.Branches, func(branch types.Branch) bool {
2116
+
return branch.Name == head || branch.Name == base
2117
+
}) {
2118
+
allowPull = true
2119
+
}
2120
+
}
2121
+
2122
s.pages.RepoCompare(w, pages.RepoCompareParams{
2123
LoggedInUser: user,
2124
RepoInfo: f.RepoInfo(s, user),
···
2127
Tags: tags.Tags,
2128
Base: base,
2129
Head: head,
2130
+
AllowPull: allowPull,
2131
+
})
2132
+
2133
+
}
2134
+
2135
+
func (s *State) RepoCompareAllowPullFragment(w http.ResponseWriter, r *http.Request) {
2136
+
user := s.oauth.GetUser(r)
2137
+
f, err := s.fullyResolvedRepo(r)
2138
+
if err != nil {
2139
+
log.Println("failed to get repo and knot", err)
2140
+
return
2141
+
}
2142
+
2143
+
s.pages.RepoCompareAllowPullFragment(w, pages.RepoCompareAllowPullParams{
2144
+
Head: chi.URLParam(r, "head"),
2145
+
Base: chi.URLParam(r, "base"),
2146
+
RepoInfo: f.RepoInfo(s, user),
2147
+
LoggedInUser: user,
2148
})
2149
}
2150
+2
-1
appview/state/router.go
+2
-1
appview/state/router.go
···
127
// /compare/master...some/feature
128
// /compare/master...example.com:another/feature <- this is a fork
129
r.Get("/{base}/{head}", s.RepoCompare)
130
r.Get("/*", s.RepoCompare)
131
-
r.Get("/diff/{base}/{head}", s.RepoCompareDiffFragment)
132
})
133
134
r.Route("/pulls", func(r chi.Router) {
···
127
// /compare/master...some/feature
128
// /compare/master...example.com:another/feature <- this is a fork
129
r.Get("/{base}/{head}", s.RepoCompare)
130
+
r.Get("/diff/{base}/{head}", s.RepoCompareDiffFragment)
131
+
r.Get("/allow-pull/{base}/{head}", s.RepoCompareAllowPullFragment)
132
r.Get("/*", s.RepoCompare)
133
})
134
135
r.Route("/pulls", func(r chi.Router) {