This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

appview: upload images as blobs (pulls)

Signed-off-by: Wilhelm Berggren <wilhelmberggren@gmail.com>
Signed-off-by: Seongmin Lee <git@boltless.me>

author
Wilhelm Berggren
committer
Seongmin Lee
date (Jul 29, 2026, 1:37 AM +0900) commit dd07ef9c parent 7dcf032e change-id twzmprmx
+42 -10
+2
appview/models/pull.go
··· 74 74 Submissions []*PullSubmission 75 75 Mentions []syntax.DID 76 76 References []syntax.ATURI 77 + Blobs []*lexutil.LexBlob 77 78 78 79 // stacking 79 80 DependentOn *syntax.ATURI ··· 115 116 Mentions: mentions, 116 117 References: references, 117 118 CreatedAt: p.Created.Format(time.RFC3339), 119 + Blobs: p.Blobs, 118 120 Target: &tangled.RepoPull_Target{ 119 121 Repo: string(p.RepoDid), 120 122 Branch: p.TargetBranch,
+16 -3
appview/pulls/compose.go
··· 130 130 131 131 stackTitles := parseBracketedForm(r.Form, "stackTitle") 132 132 stackBodies := parseBracketedForm(r.Form, "stackBody") 133 + stackBlobs := parseStackBlobForms(r.Form) 133 134 134 135 // Handle the PR creation based on the type 135 136 if isBranchBased { ··· 137 138 s.pages.Notice(w, "pull", "This knot doesn't support branch-based pull requests. Try another way?") 138 139 return 139 140 } 140 - s.handleBranchBasedPull(w, r, f, userDid, title, body, targetBranch, sourceBranch, isStacked, stackTitles, stackBodies) 141 + s.handleBranchBasedPull(w, r, f, userDid, title, body, targetBranch, sourceBranch, isStacked, stackTitles, stackBodies, stackBlobs) 141 142 } else if isForkBased { 142 143 if !caps.PullRequests.ForkSubmissions { 143 144 s.pages.Notice(w, "pull", "This knot doesn't support fork-based pull requests. Try another way?") 144 145 return 145 146 } 146 - s.handleForkBasedPull(w, r, f, userDid, fromFork, title, body, targetBranch, sourceBranch, isStacked, stackTitles, stackBodies) 147 + s.handleForkBasedPull(w, r, f, userDid, fromFork, title, body, targetBranch, sourceBranch, isStacked, stackTitles, stackBodies, stackBlobs) 147 148 } else if isPatchBased { 148 149 if !caps.PullRequests.PatchSubmissions { 149 150 s.pages.Notice(w, "pull", "This knot doesn't support patch-based pull requests. Send your patch over email.") 150 151 return 151 152 } 152 - s.handlePatchBasedPull(w, r, f, userDid, title, body, targetBranch, patch, isStacked, stackTitles, stackBodies) 153 + s.handlePatchBasedPull(w, r, f, userDid, title, body, targetBranch, patch, isStacked, stackTitles, stackBodies, stackBlobs) 153 154 } 154 155 return 155 156 } ··· 506 507 continue 507 508 } 508 509 out[parts[0]] = vals[0] 510 + } 511 + return out 512 + } 513 + 514 + func parseStackBlobForms(form url.Values) map[string][]string { 515 + out := make(map[string][]string) 516 + for key, vals := range form { 517 + parts, ok := bracketComponents(key, "stackBlobs") 518 + if !ok || len(parts) != 1 || parts[0] == "" || len(vals) == 0 { 519 + continue 520 + } 521 + out[parts[0]] = vals 509 522 } 510 523 return out 511 524 }
+14 -6
appview/pulls/create.go
··· 38 38 sourceBranch string, 39 39 isStacked bool, 40 40 stackTitles, stackBodies map[string]string, 41 + stackBlobs map[string][]string, 41 42 ) { 42 43 l := s.logger.With("handler", "handleBranchBasedPull", "user", userDid, "target_branch", targetBranch, "source_branch", sourceBranch, "is_stacked", isStacked) 43 44 ··· 81 82 Branch: sourceBranch, 82 83 } 83 84 84 - s.createPullRequest(w, r, repo, userDid, title, body, targetBranch, patch, combined, sourceRev, pullSource, isStacked, stackTitles, stackBodies) 85 + s.createPullRequest(w, r, repo, userDid, title, body, targetBranch, patch, combined, sourceRev, pullSource, isStacked, stackTitles, stackBodies, stackBlobs) 85 86 } 86 87 87 - func (s *Pulls) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, userDid syntax.DID, title, body, targetBranch, patch string, isStacked bool, stackTitles, stackBodies map[string]string) { 88 + func (s *Pulls) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, userDid syntax.DID, title, body, targetBranch, patch string, isStacked bool, stackTitles, stackBodies map[string]string, stackBlobs map[string][]string) { 88 89 if err := validatePatch(&patch); err != nil { 89 90 s.logger.Error("patch validation failed", "err", err) 90 91 s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.") 91 92 return 92 93 } 93 94 94 - s.createPullRequest(w, r, repo, userDid, title, body, targetBranch, patch, "", "", nil, isStacked, stackTitles, stackBodies) 95 + s.createPullRequest(w, r, repo, userDid, title, body, targetBranch, patch, "", "", nil, isStacked, stackTitles, stackBodies, stackBlobs) 95 96 } 96 97 97 - func (s *Pulls) handleForkBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, userDid syntax.DID, forkRepoDid string, title, body, targetBranch, sourceBranch string, isStacked bool, stackTitles, stackBodies map[string]string) { 98 + func (s *Pulls) handleForkBasedPull(w http.ResponseWriter, r *http.Request, repo *models.Repo, userDid syntax.DID, forkRepoDid string, title, body, targetBranch, sourceBranch string, isStacked bool, stackTitles, stackBodies map[string]string, stackBlobs map[string][]string) { 98 99 l := s.logger.With("handler", "handleForkBasedPull", "user", userDid, "fork_repo_did", forkRepoDid, "target_branch", targetBranch, "source_branch", sourceBranch, "is_stacked", isStacked) 99 100 100 101 if forkRepoDid == "" { ··· 190 191 RepoDid: &forkDid, 191 192 } 192 193 193 - s.createPullRequest(w, r, repo, userDid, title, body, targetBranch, patch, combined, sourceRev, pullSource, isStacked, stackTitles, stackBodies) 194 + s.createPullRequest(w, r, repo, userDid, title, body, targetBranch, patch, combined, sourceRev, pullSource, isStacked, stackTitles, stackBodies, stackBlobs) 194 195 } 195 196 196 197 func (s *Pulls) createPullRequest( ··· 205 206 pullSource *models.PullSource, 206 207 isStacked bool, 207 208 stackTitles, stackBodies map[string]string, 209 + stackBlobs map[string][]string, 208 210 ) { 209 211 l := s.logger.With("handler", "createPullRequest", "user", userDid, "target_branch", targetBranch, "is_stacked", isStacked) 210 212 ··· 221 223 pullSource, 222 224 stackTitles, 223 225 stackBodies, 226 + stackBlobs, 224 227 ) 225 228 return 226 229 } ··· 297 300 Created: now, 298 301 Repo: repo, 299 302 } 303 + 304 + pull.Blobs = models.ParseBlobs(r.PostForm["blobs"], body) 300 305 301 306 record := pull.AsRecord() 302 307 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ ··· 348 353 sourceRev string, 349 354 pullSource *models.PullSource, 350 355 stackTitles, stackBodies map[string]string, 356 + stackBlobs map[string][]string, 351 357 ) { 352 358 l := s.logger.With("handler", "createStackedPullRequest", "user", userDid, "target_branch", targetBranch, "source_rev", sourceRev) 353 359 ··· 388 394 } 389 395 390 396 // build a stack out of this patch 391 - stack, err := s.newStack(r.Context(), repo, userDid, targetBranch, pullSource, formatPatches, blobs, stackTitles, stackBodies) 397 + stack, err := s.newStack(r.Context(), repo, userDid, targetBranch, pullSource, formatPatches, blobs, stackTitles, stackBodies, stackBlobs) 392 398 if err != nil { 393 399 l.Error("failed to create stack", "err", err) 394 400 s.pages.Notice(w, "pull", fmt.Sprintf("Failed to create stack: %v", err)) ··· 464 470 formatPatches []types.FormatPatch, 465 471 blobs []*lexutil.LexBlob, 466 472 stackTitles, stackBodies map[string]string, 473 + stackBlobs map[string][]string, 467 474 ) (models.Stack, error) { 468 475 var stack models.Stack 469 476 var parentAtUri *syntax.ATURI ··· 513 520 DependentOn: parentAtUri, 514 521 Repo: repo, 515 522 } 523 + pull.Blobs = models.ParseBlobs(stackBlobs[cid], body) 516 524 517 525 stack = append(stack, &pull) 518 526
+9
appview/pulls/edit.go
··· 53 53 return 54 54 } 55 55 56 + // merge existing pins with new uploads, dropping any removed from body 57 + var existingBlobs []*lexutil.LexBlob 58 + if ex.Value != nil { 59 + if prev, ok := ex.Value.Val.(*tangled.RepoPull); ok { 60 + existingBlobs = prev.Blobs 61 + } 62 + } 63 + newPull.Blobs = models.MergeBlobs(existingBlobs, r.PostForm["blobs"], newPull.Body) 64 + 56 65 newRecord := newPull.AsRecord() 57 66 _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 58 67 Collection: tangled.RepoPullNSID,
+1 -1
appview/pulls/resubmit.go
··· 407 407 blobs[i] = blob.Blob 408 408 } 409 409 410 - newStack, err := s.newStack(r.Context(), repo, userDid, targetBranch, pull.PullSource, formatPatches, blobs, nil, nil) 410 + newStack, err := s.newStack(r.Context(), repo, userDid, targetBranch, pull.PullSource, formatPatches, blobs, nil, nil, nil) 411 411 if err != nil { 412 412 l.Error("failed to create resubmitted stack", "err", err) 413 413 s.pages.Notice(w, "pull-resubmit-error", "Failed to resubmit pull request. Try again later.")