+15
appview/pages/pages.go
+15
appview/pages/pages.go
···
557
return p.executeRepo("repo/pulls/pull", w, params)
558
}
559
560
+
type RepoPullPatchParams struct {
561
+
LoggedInUser *auth.User
562
+
DidHandleMap map[string]string
563
+
RepoInfo RepoInfo
564
+
Pull *db.Pull
565
+
Diff types.NiceDiff
566
+
Round int
567
+
Submission *db.PullSubmission
568
+
}
569
+
570
+
// this name is a mouthful
571
+
func (p *Pages) RepoPullPatchPage(w io.Writer, params RepoPullPatchParams) error {
572
+
return p.execute("repo/pulls/patch", w, params)
573
+
}
574
+
575
func (p *Pages) Static() http.Handler {
576
sub, err := fs.Sub(files, "static")
577
if err != nil {
+90
appview/pages/templates/repo/pulls/patch.html
+90
appview/pages/templates/repo/pulls/patch.html
···
···
1
+
{{ define "title" }}
2
+
viewing patch of {{ .Pull.Title }} · pull #{{ .Pull.PullId }} · {{ .RepoInfo.FullName }}
3
+
{{ end }}
4
+
5
+
{{ define "content" }}
6
+
{{ $oneIndexedRound := add .Round 1 }}
7
+
{{ $stat := .Diff.Stat }}
8
+
<div class="flex gap-2 items-center text-gray-500 mb-2 px-6">
9
+
<a href="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/" class="flex items-center gap-2">
10
+
<i data-lucide="arrow-left" class="w-4 h-4"></i>
11
+
back
12
+
</a>
13
+
<span class="select-none before:content-['·']"></span>
14
+
viewing round
15
+
<span class="text-black">#{{ $oneIndexedRound }}</span>
16
+
</div>
17
+
<div class="rounded drop-shadow-sm bg-white py-4 px-6">
18
+
<header class="pb-4">
19
+
<h1 class="text-2xl">
20
+
{{ .Pull.Title }}
21
+
<span class="text-gray-500">#{{ .Pull.PullId }}</span>
22
+
</h1>
23
+
</header>
24
+
25
+
{{ $bgColor := "bg-gray-800" }}
26
+
{{ $icon := "ban" }}
27
+
28
+
{{ if .Pull.State.IsOpen }}
29
+
{{ $bgColor = "bg-green-600" }}
30
+
{{ $icon = "git-pull-request" }}
31
+
{{ else if .Pull.State.IsMerged }}
32
+
{{ $bgColor = "bg-purple-600" }}
33
+
{{ $icon = "git-merge" }}
34
+
{{ end }}
35
+
36
+
<section>
37
+
<div class="flex items-center gap-2">
38
+
<div
39
+
id="state"
40
+
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"
41
+
>
42
+
<i
43
+
data-lucide="{{ $icon }}"
44
+
class="w-4 h-4 mr-1.5 text-white"
45
+
></i>
46
+
<span class="text-white">{{ .Pull.State.String }}</span>
47
+
</div>
48
+
<span class="text-gray-500 text-sm">
49
+
opened by
50
+
{{ $owner := index $.DidHandleMap .Pull.OwnerDid }}
51
+
<a href="/{{ $owner }}" class="no-underline hover:underline"
52
+
>{{ $owner }}</a
53
+
>
54
+
<span class="select-none before:content-['\00B7']"></span>
55
+
<time>{{ .Pull.Created | timeFmt }}</time>
56
+
<span class="select-none before:content-['\00B7']"></span>
57
+
<span>targeting branch
58
+
<span class="text-xs rounded bg-gray-100 text-black font-mono px-2 mx-1/2 inline-flex items-center">
59
+
{{ .Pull.TargetBranch }}
60
+
</span>
61
+
</span>
62
+
</span>
63
+
</div>
64
+
65
+
{{ if .Pull.Body }}
66
+
<article id="body" class="mt-2 prose">
67
+
{{ .Pull.Body | markdown }}
68
+
</article>
69
+
{{ end }}
70
+
</section>
71
+
72
+
<div id="diff-stat">
73
+
<br>
74
+
<strong class="text-sm uppercase mb-4">Changed files</strong>
75
+
{{ range .Diff.Diff }}
76
+
<ul>
77
+
{{ if .IsDelete }}
78
+
<li><a href="#file-{{ .Name.Old }}">{{ .Name.Old }}</a></li>
79
+
{{ else }}
80
+
<li><a href="#file-{{ .Name.New }}">{{ .Name.New }}</a></li>
81
+
{{ end }}
82
+
</ul>
83
+
{{ end }}
84
+
</div>
85
+
</div>
86
+
<section>
87
+
{{ template "fragments/diff" (list .RepoInfo.FullName .Diff) }}
88
+
</section>
89
+
{{ end }}
90
+
+3
-5
appview/pages/templates/repo/pulls/pull.html
+3
-5
appview/pages/templates/repo/pulls/pull.html
···
51
</div>
52
53
{{ if .Pull.Body }}
54
-
<article id="body" class="mt-8 prose">
55
{{ .Pull.Body | markdown }}
56
</article>
57
{{ end }}
···
117
{{ $s = "" }}
118
{{ end }}
119
{{ len .Comments }} comment{{$s}}
120
</span>
121
</div>
122
</div>
123
</summary>
124
<div class="pl-12 flex flex-col gap-2 mt-2 relative">
125
-
<div>
126
-
{{ template "fragments/diff" (list $repoName $diff) }}
127
-
</div>
128
-
129
{{ range .Comments }}
130
<div id="comment-{{.ID}}" class="bg-white rounded drop-shadow-sm py-2 px-4 relative w-fit">
131
<div class="absolute left-8 -top-2 w-px h-2 bg-gray-300"></div>
···
51
</div>
52
53
{{ if .Pull.Body }}
54
+
<article id="body" class="mt-2 prose">
55
{{ .Pull.Body | markdown }}
56
</article>
57
{{ end }}
···
117
{{ $s = "" }}
118
{{ end }}
119
{{ len .Comments }} comment{{$s}}
120
+
<span class="before:content-['·']"></span>
121
+
<a href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}">view patch</a>
122
</span>
123
</div>
124
</div>
125
</summary>
126
<div class="pl-12 flex flex-col gap-2 mt-2 relative">
127
{{ range .Comments }}
128
<div id="comment-{{.ID}}" class="bg-white rounded drop-shadow-sm py-2 px-4 relative w-fit">
129
<div class="absolute left-8 -top-2 w-px h-2 bg-gray-300"></div>
+47
appview/state/pull.go
+47
appview/state/pull.go
···
10
"strings"
11
"time"
12
13
"github.com/sotangled/tangled/api/tangled"
14
"github.com/sotangled/tangled/appview/db"
15
"github.com/sotangled/tangled/appview/pages"
···
100
Pull: *pull,
101
MergeCheck: mergeCheckResponse,
102
})
103
}
104
105
func (s *State) RepoPulls(w http.ResponseWriter, r *http.Request) {
···
10
"strings"
11
"time"
12
13
+
"github.com/go-chi/chi/v5"
14
"github.com/sotangled/tangled/api/tangled"
15
"github.com/sotangled/tangled/appview/db"
16
"github.com/sotangled/tangled/appview/pages"
···
101
Pull: *pull,
102
MergeCheck: mergeCheckResponse,
103
})
104
+
}
105
+
106
+
func (s *State) RepoPullPatch(w http.ResponseWriter, r *http.Request) {
107
+
user := s.auth.GetUser(r)
108
+
f, err := fullyResolvedRepo(r)
109
+
if err != nil {
110
+
log.Println("failed to get repo and knot", err)
111
+
return
112
+
}
113
+
114
+
pull, ok := r.Context().Value("pull").(*db.Pull)
115
+
if !ok {
116
+
log.Println("failed to get pull")
117
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
118
+
return
119
+
}
120
+
121
+
roundId := chi.URLParam(r, "round")
122
+
roundIdInt, err := strconv.Atoi(roundId)
123
+
if err != nil || roundIdInt >= len(pull.Submissions) {
124
+
http.Error(w, "bad round id", http.StatusBadRequest)
125
+
log.Println("failed to parse round id", err)
126
+
return
127
+
}
128
+
129
+
identsToResolve := []string{pull.OwnerDid}
130
+
resolvedIds := s.resolver.ResolveIdents(r.Context(), identsToResolve)
131
+
didHandleMap := make(map[string]string)
132
+
for _, identity := range resolvedIds {
133
+
if !identity.Handle.IsInvalidHandle() {
134
+
didHandleMap[identity.DID.String()] = fmt.Sprintf("@%s", identity.Handle.String())
135
+
} else {
136
+
didHandleMap[identity.DID.String()] = identity.DID.String()
137
+
}
138
+
}
139
+
140
+
s.pages.RepoPullPatchPage(w, pages.RepoPullPatchParams{
141
+
LoggedInUser: user,
142
+
DidHandleMap: didHandleMap,
143
+
RepoInfo: f.RepoInfo(s, user),
144
+
Pull: pull,
145
+
Round: roundIdInt,
146
+
Submission: pull.Submissions[roundIdInt],
147
+
Diff: pull.Submissions[roundIdInt].AsNiceDiff(pull.TargetBranch),
148
+
})
149
+
150
}
151
152
func (s *State) RepoPulls(w http.ResponseWriter, r *http.Request) {
+1
-1
appview/state/router.go
+1
-1
appview/state/router.go