diff --git a/appview/pages/pages.go b/appview/pages/pages.go
index c861df6a..0a443c55 100644
--- a/appview/pages/pages.go
+++ b/appview/pages/pages.go
@@ -1468,6 +1468,16 @@ func (p *Pages) MarkdownPreviewFragment(w io.Writer, body string) error {
return p.executePlain("fragments/markdownPreview", w, body)
}
+type EditPullParams struct {
+ LoggedInUser *oauth.MultiAccountUser
+ RepoInfo repoinfo.RepoInfo
+ Pull *models.Pull
+}
+
+func (p *Pages) EditPullFragment(w io.Writer, params EditPullParams) error {
+ return p.executePlain("repo/pulls/fragments/pullEdit", w, params)
+}
+
type RepoPullsParams struct {
BaseParams
RepoInfo repoinfo.RepoInfo
diff --git a/appview/pages/templates/repo/pulls/fragments/pullEdit.html b/appview/pages/templates/repo/pulls/fragments/pullEdit.html
new file mode 100644
index 00000000..2f956dfa
--- /dev/null
+++ b/appview/pages/templates/repo/pulls/fragments/pullEdit.html
@@ -0,0 +1,42 @@
+{{ define "repo/pulls/fragments/pullEdit" }}
+
+{{ end }}
diff --git a/appview/pages/templates/repo/pulls/fragments/pullHeader.html b/appview/pages/templates/repo/pulls/fragments/pullHeader.html
index 182a8451..c1b0fc89 100644
--- a/appview/pages/templates/repo/pulls/fragments/pullHeader.html
+++ b/appview/pages/templates/repo/pulls/fragments/pullHeader.html
@@ -1,12 +1,12 @@
{{ define "repo/pulls/fragments/pullHeader" }}
-
-
- {{ .Pull.Title | description }}
- #{{ .Pull.PullId }}
-
-
+
+
+
+ {{ .Pull.Title | description }}
+ #{{ .Pull.PullId }}
+
+
-
{{ template "repo/pulls/fragments/pullState" .Pull.State }}
@@ -39,6 +39,16 @@
{{ end }}
{{ end }}
+
+ {{ if and .LoggedInUser (eq .LoggedInUser.Did .Pull.OwnerDid) }}
+
+ {{ i "pencil" "size-3" }}
+
+ {{ end }}
diff --git a/appview/pulls/edit.go b/appview/pulls/edit.go
new file mode 100644
index 00000000..d4332abc
--- /dev/null
+++ b/appview/pulls/edit.go
@@ -0,0 +1,95 @@
+package pulls
+
+import (
+ "net/http"
+
+ comatproto "github.com/bluesky-social/indigo/api/atproto"
+ lexutil "github.com/bluesky-social/indigo/lex/util"
+
+ "tangled.org/core/api/tangled"
+ "tangled.org/core/appview/db"
+ "tangled.org/core/appview/models"
+ "tangled.org/core/appview/pages"
+)
+
+func (s *Pulls) EditPull(w http.ResponseWriter, r *http.Request) {
+ l := s.logger.With("handler", "EditPull")
+ user := s.oauth.GetMultiAccountUser(r)
+ ctx := r.Context()
+
+ pull, ok := r.Context().Value("pull").(*models.Pull)
+ if !ok {
+ l.Error("failed to get pull")
+ s.pages.Error404(w)
+ return
+ }
+
+ switch r.Method {
+ case http.MethodGet:
+ s.pages.EditPullFragment(w, pages.EditPullParams{
+ LoggedInUser: user,
+ RepoInfo: s.repoResolver.GetRepoInfo(r, user),
+ Pull: pull,
+ })
+ case http.MethodPost:
+ noticeId := "pulls"
+ newPull := *pull
+ newPull.Title = r.FormValue("title")
+ newPull.Body = r.FormValue("body")
+ newPull.Mentions, newPull.References = s.mentionsResolver.Resolve(ctx, newPull.Body)
+
+ // edit an atproto record
+ client, err := s.oauth.AuthorizedClient(r)
+ if err != nil {
+ l.Error("failed to get authorized client", "err", err)
+ s.pages.Notice(w, noticeId, "Failed to edit pull.")
+ return
+ }
+
+ ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoPullNSID, user.Did, newPull.Rkey)
+ if err != nil {
+ l.Error("failed to get record", "err", err)
+ s.pages.Notice(w, noticeId, "Failed to edit pull, no record found on PDS.")
+ return
+ }
+
+ newRecord := newPull.AsRecord()
+ _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
+ Collection: tangled.RepoPullNSID,
+ Repo: user.Did,
+ Rkey: newPull.Rkey,
+ SwapRecord: ex.Cid,
+ Record: &lexutil.LexiconTypeDecoder{
+ Val: &newRecord,
+ },
+ })
+ if err != nil {
+ l.Error("failed to edit record on PDS", "err", err)
+ s.pages.Notice(w, noticeId, "Failed to edit pull on PDS.")
+ return
+ }
+
+ tx, err := s.db.BeginTx(r.Context(), nil)
+ if err != nil {
+ l.Error("failed to start tx", "err", err)
+ s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
+ return
+ }
+ defer tx.Rollback()
+
+ err = db.PutPull(tx, &newPull)
+ if err != nil {
+ l.Error("failed to create pull request in database", "err", err)
+ s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
+ return
+ }
+
+ if err = tx.Commit(); err != nil {
+ l.Error("failed to commit transaction for pull request", "err", err)
+ s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
+ return
+ }
+
+ s.pages.HxRefresh(w)
+ }
+}
diff --git a/appview/pulls/router.go b/appview/pulls/router.go
index 6d7dfe66..ad02e2cd 100644
--- a/appview/pulls/router.go
+++ b/appview/pulls/router.go
@@ -35,6 +35,8 @@ func (s *Pulls) Router(mw *middleware.Middleware) http.Handler {
r.Group(func(r chi.Router) {
r.Use(middleware.AuthMiddleware(s.oauth))
+ r.Get("/edit", s.EditPull)
+ r.Post("/edit", s.EditPull)
r.Route("/resubmit", func(r chi.Router) {
r.Get("/", s.ResubmitPull)
r.Post("/", s.ResubmitPull)