···
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)
-
log.Println("failed to get repo and knot", err)
-
issueId := chi.URLParam(r, "issue")
-
issueIdInt, err := strconv.Atoi(issueId)
-
http.Error(w, "bad issue id", http.StatusBadRequest)
-
log.Println("failed to parse issue id", err)
-
body := r.FormValue("body")
-
rp.pages.Notice(w, "issue", "Body is required")
-
commentId := mathrand.IntN(1000000)
-
err := db.NewIssueComment(rp.db, &db.Comment{
-
log.Println("failed to create comment", err)
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
-
createdAt := time.Now().Format(time.RFC3339)
-
issueAt, err := db.GetIssueAt(rp.db, f.RepoAt(), issueIdInt)
-
log.Println("failed to get issue at", err)
-
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
-
atUri := f.RepoAt().String()
-
client, err := rp.oauth.AuthorizedClient(r)
-
log.Println("failed to get authorized client", err)
-
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
-
_, err = client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{
-
Collection: tangled.RepoIssueCommentNSID,
-
Record: &lexutil.LexiconTypeDecoder{
-
Val: &tangled.RepoIssueComment{
-
log.Println("failed to create comment", err)
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
-
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d#comment-%d", f.OwnerSlashRepo(), issueIdInt, commentId))
-
func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) {
-
user := rp.oauth.GetUser(r)
-
f, err := rp.repoResolver.Resolve(r)
-
log.Println("failed to get repo and knot", err)
-
issueId := chi.URLParam(r, "issue")
-
issueIdInt, err := strconv.Atoi(issueId)
-
http.Error(w, "bad issue id", http.StatusBadRequest)
-
log.Println("failed to parse issue id", err)
-
commentId := chi.URLParam(r, "comment_id")
-
commentIdInt, err := strconv.Atoi(commentId)
-
http.Error(w, "bad comment id", http.StatusBadRequest)
-
log.Println("failed to parse issue id", err)
-
issue, err := db.GetIssue(rp.db, f.RepoAt(), issueIdInt)
-
log.Println("failed to get issue", err)
-
rp.pages.Notice(w, "issues", "Failed to load issue. Try again later.")
-
comment, err := db.GetComment(rp.db, f.RepoAt(), issueIdInt, commentIdInt)
-
http.Error(w, "bad comment id", http.StatusBadRequest)
-
rp.pages.SingleIssueCommentFragment(w, pages.SingleIssueCommentParams{
RepoInfo: f.RepoInfo(user),
func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) {
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)
-
log.Println("failed to get repo and knot", err)
-
issueId := chi.URLParam(r, "issue")
-
issueIdInt, err := strconv.Atoi(issueId)
-
http.Error(w, "bad issue id", http.StatusBadRequest)
-
log.Println("failed to parse issue id", err)
-
commentId := chi.URLParam(r, "comment_id")
-
commentIdInt, err := strconv.Atoi(commentId)
-
http.Error(w, "bad comment id", http.StatusBadRequest)
-
log.Println("failed to parse issue id", err)
-
issue, err := db.GetIssue(rp.db, f.RepoAt(), issueIdInt)
-
log.Println("failed to get issue", err)
-
rp.pages.Notice(w, "issues", "Failed to load issue. Try again later.")
-
comment, err := db.GetComment(rp.db, f.RepoAt(), issueIdInt, commentIdInt)
-
http.Error(w, "bad comment id", http.StatusBadRequest)
-
if comment.OwnerDid != user.Did {
http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
···
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
-
err = db.EditComment(rp.db, comment.RepoAt, comment.Issue, comment.CommentId, newBody)
log.Println("failed to perferom update-description query", err)
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
···
func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) {
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)
-
log.Println("failed to get repo and knot", err)
···
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)
+
l.Error("failed to get repo and knot", "err", err)
+
issue, ok := r.Context().Value("issue").(*db.Issue)
+
l.Error("failed to get issue")
+
body := r.FormValue("body")
+
rp.pages.Notice(w, "issue", "Body is required")
+
replyToUri := r.FormValue("reply-to")
+
uri, err := syntax.ParseATURI(replyToUri)
+
l.Error("failed to get parse replyTo", "err", err, "replyTo", replyToUri)
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
if uri.Collection() != tangled.RepoIssueCommentNSID {
+
l.Error("invalid replyTo collection", "collection", uri.Collection())
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
comment := db.IssueComment{
+
IssueAt: issue.AtUri().String(),
+
if err = rp.validator.ValidateIssueComment(&comment); err != nil {
+
l.Error("failed to validate comment", "err", err)
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
record := comment.AsRecord()
+
client, err := rp.oauth.AuthorizedClient(r)
+
l.Error("failed to get authorized client", "err", err)
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
// create a record first
+
resp, err := client.RepoPutRecord(r.Context(), &comatproto.RepoPutRecord_Input{
+
Collection: tangled.RepoIssueCommentNSID,
+
Record: &lexutil.LexiconTypeDecoder{
+
l.Error("failed to create comment", "err", err)
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
if err := rollbackRecord(context.Background(), atUri, client); err != nil {
+
l.Error("rollback failed", "err", err)
+
commentId, err := db.AddIssueComment(rp.db, comment)
+
l.Error("failed to create comment", "err", err)
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
// reset atUri to make rollback a no-op
+
rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d#comment-%d", f.OwnerSlashRepo(), issue.IssueId, commentId))
+
func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) {
+
l := rp.logger.With("handler", "IssueComment")
+
user := rp.oauth.GetUser(r)
+
f, err := rp.repoResolver.Resolve(r)
+
l.Error("failed to get repo and knot", "err", err)
+
issue, ok := r.Context().Value("issue").(*db.Issue)
+
l.Error("failed to get issue")
+
commentId := chi.URLParam(r, "commentId")
+
comments, err := db.GetIssueComments(
+
db.FilterEq("id", commentId),
+
l.Error("failed to fetch comment", "id", commentId)
+
http.Error(w, "failed to fetch comment id", http.StatusBadRequest)
+
if len(comments) != 1 {
+
l.Error("incorrect number of comments returned", "id", commentId, "len(comments)", len(comments))
+
http.Error(w, "invalid comment id", http.StatusBadRequest)
+
rp.pages.IssueCommentBodyFragment(w, pages.IssueCommentBodyParams{
RepoInfo: f.RepoInfo(user),
func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) {
+
l := rp.logger.With("handler", "EditIssueComment")
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)
+
l.Error("failed to get repo and knot", "err", err)
+
issue, ok := r.Context().Value("issue").(*db.Issue)
+
l.Error("failed to get issue")
+
commentId := chi.URLParam(r, "commentId")
+
comments, err := db.GetIssueComments(
+
db.FilterEq("id", commentId),
+
l.Error("failed to fetch comment", "id", commentId)
+
http.Error(w, "failed to fetch comment id", http.StatusBadRequest)
+
if len(comments) != 1 {
+
l.Error("incorrect number of comments returned", "id", commentId, "len(comments)", len(comments))
+
http.Error(w, "invalid comment id", http.StatusBadRequest)
+
if comment.Did != user.Did {
+
l.Error("unauthorized comment edit", "expectedDid", comment.Did, "gotDid", user.Did)
http.Error(w, "you are not the author of this comment", http.StatusUnauthorized)
···
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
+
newComment.Body = newBody
+
newComment.Edited = &now
+
record := newComment.AsRecord()
+
_, err = db.AddIssueComment(rp.db, newComment)
log.Println("failed to perferom update-description query", err)
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
···
+
func (rp *Issues) ReplyIssueCommentPlaceholder(w http.ResponseWriter, r *http.Request) {
+
l := rp.logger.With("handler", "ReplyIssueCommentPlaceholder")
+
user := rp.oauth.GetUser(r)
+
f, err := rp.repoResolver.Resolve(r)
+
l.Error("failed to get repo and knot", "err", err)
+
issue, ok := r.Context().Value("issue").(*db.Issue)
+
l.Error("failed to get issue")
+
commentId := chi.URLParam(r, "commentId")
+
comments, err := db.GetIssueComments(
+
db.FilterEq("id", commentId),
+
l.Error("failed to fetch comment", "id", commentId)
+
http.Error(w, "failed to fetch comment id", http.StatusBadRequest)
+
if len(comments) != 1 {
+
l.Error("incorrect number of comments returned", "id", commentId, "len(comments)", len(comments))
+
http.Error(w, "invalid comment id", http.StatusBadRequest)
+
rp.pages.ReplyIssueCommentPlaceholderFragment(w, pages.ReplyIssueCommentPlaceholderParams{
+
RepoInfo: f.RepoInfo(user),
+
func (rp *Issues) ReplyIssueComment(w http.ResponseWriter, r *http.Request) {
+
l := rp.logger.With("handler", "ReplyIssueComment")
+
user := rp.oauth.GetUser(r)
+
f, err := rp.repoResolver.Resolve(r)
+
l.Error("failed to get repo and knot", "err", err)
+
issue, ok := r.Context().Value("issue").(*db.Issue)
+
l.Error("failed to get issue")
+
commentId := chi.URLParam(r, "commentId")
+
comments, err := db.GetIssueComments(
+
db.FilterEq("id", commentId),
+
l.Error("failed to fetch comment", "id", commentId)
+
http.Error(w, "failed to fetch comment id", http.StatusBadRequest)
+
if len(comments) != 1 {
+
l.Error("incorrect number of comments returned", "id", commentId, "len(comments)", len(comments))
+
http.Error(w, "invalid comment id", http.StatusBadRequest)
+
rp.pages.ReplyIssueCommentFragment(w, pages.ReplyIssueCommentParams{
+
RepoInfo: f.RepoInfo(user),
func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) {
+
l := rp.logger.With("handler", "DeleteIssueComment")
user := rp.oauth.GetUser(r)
f, err := rp.repoResolver.Resolve(r)