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" }} +
+
+
+ + +
+
+ + {{ template "fragments/markdownEditor" + (dict "Name" "body" + "Value" .Pull.Body + "BlobName" "blob" + "Rows" 15 + "Placeholder" "Describe your pull request. Markdown is supported.") }} +
+
+
+
+ + {{ i "x" "size-4" }} + Cancel + + +
+
+
+
+{{ 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)