Monorepo for Tangled tangled.org
2

Configure Feed

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

appview/{repo,pages}: avoid embedding xrpc response to page params

Directly embedding xrpc response to page parameter makes super hard to
track which value is used where.

Signed-off-by: Seongmin Lee <git@boltless.me>

author
Seongmin Lee
committer
Tangled
date (Jun 11, 2026, 10:52 AM +0300) commit c90cec2e parent e2b215b1 change-id lkwzwork
+54 -48
+8 -2
appview/pages/pages.go
··· 987 987 HTMLReadme template.HTML 988 988 EmailToDid map[string]string 989 989 LastCommitInfo *types.LastCommitInfo 990 - types.RepoTreeResponse 990 + Ref string 991 + Parent string 992 + DotDot string 993 + Files []types.NiceTree 994 + ReadmeFileName string 995 + Readme string 991 996 } 992 997 993 998 type RepoTreeStats struct { ··· 1092 1097 BlobView models.BlobView 1093 1098 EmailToDid map[string]string 1094 1099 LastCommitInfo *types.LastCommitInfo 1095 - *tangled.RepoBlob_Output 1100 + Ref string 1101 + Path string 1096 1102 } 1097 1103 1098 1104 func (p *Pages) RepoBlob(w io.Writer, params RepoBlobParams) error {
+8 -7
appview/repo/blob.go
··· 99 99 } 100 100 101 101 rp.pages.RepoBlob(w, pages.RepoBlobParams{ 102 - LoggedInUser: user, 103 - RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 104 - BreadCrumbs: breadcrumbs, 105 - BlobView: blobView, 106 - EmailToDid: emailToDidMap, 107 - LastCommitInfo: lastCommitInfo, 108 - RepoBlob_Output: resp, 102 + LoggedInUser: user, 103 + RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 104 + BreadCrumbs: breadcrumbs, 105 + BlobView: blobView, 106 + EmailToDid: emailToDidMap, 107 + LastCommitInfo: lastCommitInfo, 108 + Ref: resp.Ref, 109 + Path: resp.Path, 109 110 }) 110 111 } 111 112
+38 -29
appview/repo/tree.go
··· 43 43 rp.pages.Error503(w) 44 44 return 45 45 } 46 + 47 + ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f) 48 + // redirects tree paths trying to access a blob; in this case the result.Files is unpopulated, 49 + // so we can safely redirect to the "parent" (which is the same file). 50 + if len(xrpcResp.Files) == 0 && xrpcResp.Parent != nil && *xrpcResp.Parent == treePath { 51 + redirectTo := fmt.Sprintf("/%s/blob/%s/%s", ownerSlashRepo, url.PathEscape(ref), *xrpcResp.Parent) 52 + http.Redirect(w, r, redirectTo, http.StatusFound) 53 + return 54 + } 55 + 46 56 var readmeFile *tangled.GitTempGetTree_TreeEntry 47 57 // Convert XRPC response to internal types.RepoTreeResponse 48 58 files := make([]types.NiceTree, len(xrpcResp.Files)) ··· 66 76 readmeFile = xrpcFile 67 77 } 68 78 } 69 - result := types.RepoTreeResponse{ 70 - Ref: xrpcResp.Ref, 71 - Files: files, 72 - } 73 - if xrpcResp.Parent != nil { 74 - result.Parent = *xrpcResp.Parent 75 - } 76 - if xrpcResp.Dotdot != nil { 77 - result.DotDot = *xrpcResp.Dotdot 78 - } 79 + sortFiles(files) 80 + 81 + var ( 82 + readmeFileName string 83 + readmeFileContent string 84 + ) 79 85 if readmeFile != nil { 80 86 bytes, err := tangled.GitTempGetBlob(r.Context(), xrpcc, path.Join(treePath, readmeFile.Name), ref, f.RepoDid) 81 87 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { ··· 83 89 rp.pages.Error503(w) 84 90 return 85 91 } 86 - result.ReadmeFileName = readmeFile.Name 87 - result.Readme = string(bytes) 92 + readmeFileName = readmeFile.Name 93 + readmeFileContent = string(bytes) 88 94 } 89 - ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f) 90 - // redirects tree paths trying to access a blob; in this case the result.Files is unpopulated, 91 - // so we can safely redirect to the "parent" (which is the same file). 92 - if len(result.Files) == 0 && result.Parent == treePath { 93 - redirectTo := fmt.Sprintf("/%s/blob/%s/%s", ownerSlashRepo, url.PathEscape(ref), result.Parent) 94 - http.Redirect(w, r, redirectTo, http.StatusFound) 95 - return 96 - } 97 - user := rp.oauth.GetMultiAccountUser(r) 98 95 var breadcrumbs [][]string 99 96 breadcrumbs = append(breadcrumbs, []string{f.Name, fmt.Sprintf("/%s/tree/%s", ownerSlashRepo, url.PathEscape(ref))}) 100 97 if treePath != "" { ··· 102 99 breadcrumbs = append(breadcrumbs, []string{elem, fmt.Sprintf("%s/%s", breadcrumbs[idx][1], url.PathEscape(elem))}) 103 100 } 104 101 } 105 - sortFiles(result.Files) 106 102 107 103 // Get email to DID mapping for commit author 108 104 var emails []string ··· 130 126 } 131 127 } 132 128 129 + user := rp.oauth.GetMultiAccountUser(r) 133 130 rp.pages.RepoTree(w, pages.RepoTreeParams{ 134 - LoggedInUser: user, 135 - BreadCrumbs: breadcrumbs, 136 - Path: treePath, 137 - RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 138 - EmailToDid: emailToDidMap, 139 - LastCommitInfo: lastCommitInfo, 140 - RepoTreeResponse: result, 131 + LoggedInUser: user, 132 + BreadCrumbs: breadcrumbs, 133 + Path: treePath, 134 + RepoInfo: rp.repoResolver.GetRepoInfo(r, user), 135 + EmailToDid: emailToDidMap, 136 + LastCommitInfo: lastCommitInfo, 137 + Ref: xrpcResp.Ref, 138 + Parent: derefString(xrpcResp.Parent), 139 + DotDot: derefString(xrpcResp.Dotdot), 140 + Files: files, 141 + ReadmeFileName: readmeFileName, 142 + Readme: readmeFileContent, 141 143 }) 142 144 } 145 + 146 + func derefString(s *string) string { 147 + if s == nil { 148 + return "" 149 + } 150 + return *s 151 + }
-10
types/repo.go
··· 38 38 CombinedPatchRaw string `json:"combined_patch_raw,omitempty"` 39 39 } 40 40 41 - type RepoTreeResponse struct { 42 - Ref string `json:"ref,omitempty"` 43 - Parent string `json:"parent,omitempty"` 44 - Description string `json:"description,omitempty"` 45 - DotDot string `json:"dotdot,omitempty"` 46 - Files []NiceTree `json:"files,omitempty"` 47 - ReadmeFileName string `json:"readme_filename,omitempty"` 48 - Readme string `json:"readme_contents,omitempty"` 49 - } 50 - 51 41 type TagReference struct { 52 42 Reference 53 43 Tag *object.Tag `json:"tag,omitempty"`