Monorepo for Tangled tangled.org

appview: add "starred-by" page to repos #1112

open opened by pdewey.com targeting master from pdewey.com/tangled-core: feat-starred-by-page

Adds a page and route for each repo that shows all users that have starred a given repo. This divides the star button within a repo page, adding an icon to the right side that can be clicked to open the new stars page.

Closes #427

Labels

None yet.

assignee

None yet.

Participants 3
AT URI
at://did:plc:hm5f3dnm6jdhrc55qp2npdja/sh.tangled.repo.pull/3mg7bpskm4n22
+35 -51
Interdiff #2 โ†’ #3
appview/db/star.go

This file has not been changed.

+13 -13
appview/pages/pages.go
··· 675 675 IsStarred bool 676 676 SubjectAt syntax.ATURI 677 677 StarCount int 678 - StarsHref string 679 678 HxSwapOob bool 680 679 } 681 680 ··· 689 688 IsStarred bool 690 689 SubjectAt syntax.ATURI 691 690 StarCount int 691 + RepoName string 692 692 HxSwapOob bool 693 693 } 694 694 ··· 1388 1388 return p.executePlain("repo/fragments/editLabelPanel", w, params) 1389 1389 } 1390 1390 1391 - type RepoStarsParams struct { 1392 - LoggedInUser *oauth.MultiAccountUser 1393 - RepoInfo repoinfo.RepoInfo 1394 - Active string 1395 - Starrers []models.Star 1396 - } 1397 - 1398 - func (p *Pages) RepoStars(w io.Writer, params RepoStarsParams) error { 1399 - params.Active = "stars" 1400 - return p.executeRepo("repo/stars", w, params) 1401 - } 1402 - 1403 1391 type PipelinesParams struct { 1404 1392 1405 1393 ··· 1431 1419 return p.executePlain("repo/fragments/editLabelPanel", w, params) 1432 1420 } 1433 1421 1422 + type RepoStarsParams struct { 1423 + LoggedInUser *oauth.MultiAccountUser 1424 + RepoInfo repoinfo.RepoInfo 1425 + Active string 1426 + Starrers []models.Star 1427 + } 1428 + 1429 + func (p *Pages) RepoStars(w io.Writer, params RepoStarsParams) error { 1430 + params.Active = "overview" 1431 + return p.executeRepo("repo/stars", w, params) 1432 + } 1433 + 1434 1434 type PipelinesParams struct {
-4
appview/pages/repoinfo/repoinfo.go
··· 35 35 return path.Join(r.ownerWithoutAt(), r.Name) 36 36 } 37 37 38 - func (r RepoInfo) StarsHref() string { 39 - return fmt.Sprintf("/%s/stars", r.FullName()) 40 - } 41 - 42 38 func (r RepoInfo) GetTabs() [][]string { 43 39 tabs := [][]string{ 44 40 {"overview", "/", "square-chart-gantt"},
+12 -9
appview/pages/templates/fragments/starBtn.html
··· 9 9 <button 10 10 class="flex flex-1 justify-center gap-2 items-center px-2 group disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50 dark:hover:bg-gray-700" 11 11 {{ if .IsStarred }} 12 - hx-delete="/star?subject={{ .SubjectAt }}&countHint={{ .StarCount }}" 12 + hx-delete="/star?subject={{ .SubjectAt }}&countHint={{ .StarCount }}&repoName={{ .RepoName }}" 13 13 {{ else }} 14 - hx-post="/star?subject={{ .SubjectAt }}&countHint={{ .StarCount }}" 14 + hx-post="/star?subject={{ .SubjectAt }}&countHint={{ .StarCount }}&repoName={{ .RepoName }}" 15 15 {{ end }} 16 16 hx-trigger="click" 17 17 hx-disabled-elt="this" ··· 22 22 {{ i "star" "w-4 h-4 inline group-[.htmx-request]:hidden" }} 23 23 {{ end }} 24 24 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 25 - <span class="text-sm"> 26 - {{ .StarCount }} 27 - </span> 25 + <span class="text-sm md:hidden group-[.htmx-request]:hidden">{{ if .IsStarred }}unstar{{ else }}star{{ end }}</span> 28 26 </button> 29 - {{ if .StarsHref }} 27 + {{ if .RepoName }} 28 + {{ $did := .SubjectAt.Authority | string }} 30 29 <a 31 - href="{{ .StarsHref }}" 32 - class="flex items-center px-2 no-underline hover:no-underline border-l border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700" 30 + href="/{{ resolve $did }}/{{ .RepoName }}/stars" 31 + class="flex items-center px-2 text-sm no-underline hover:no-underline border-l border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700" 33 32 title="Starred by" 34 33 > 35 - {{ i "users" "w-3 h-3" }} 34 + {{ .StarCount }} 36 35 </a> 36 + {{ else }} 37 + <span class="flex items-center px-2 text-sm border-l border-gray-200 dark:border-gray-700"> 38 + {{ .StarCount }} 39 + </span> 37 40 {{ end }} 38 41 </div> 39 42 {{ end }}
+1 -1
appview/pages/templates/layouts/repobase.html
··· 116 116 (dict "SubjectAt" .RepoInfo.RepoAt 117 117 "IsStarred" .RepoInfo.IsStarred 118 118 "StarCount" .RepoInfo.Stats.StarCount 119 - "StarsHref" .RepoInfo.StarsHref) }} 119 + "RepoName" .RepoInfo.Name) }} 120 120 <a 121 121 class="btn text-sm no-underline hover:no-underline flex items-center gap-2 group" 122 122 hx-boost="true"
appview/pages/templates/repo/stars.html

This file has not been changed.

+6 -6
appview/repo/repo.go
··· 1195 1195 } 1196 1196 } 1197 1197 1198 + // this is used to rollback changes made to the PDS 1199 + // 1200 + // it is a no-op if the provided ATURI is empty 1201 + } 1202 + } 1203 + 1198 1204 func (rp *Repo) Stars(w http.ResponseWriter, r *http.Request) { 1199 1205 l := rp.logger.With("handler", "Stars") 1200 1206 ··· 1219 1225 } 1220 1226 1221 1227 // this is used to rollback changes made to the PDS 1222 - // 1223 - // it is a no-op if the provided ATURI is empty 1224 - } 1225 - } 1226 - 1227 - // this is used to rollback changes made to the PDS 1228 1228 // 1229 1229 // it is a no-op if the provided ATURI is empty
appview/repo/router.go

This file has not been changed.

+3 -18
appview/state/star.go
··· 1 1 package state 2 2 3 3 import ( 4 - "context" 5 - "fmt" 6 4 "log" 7 5 "net/http" 8 6 "time" ··· 38 36 return 39 37 } 40 38 41 - starsHref := s.starsHref(r.Context(), subjectUri) 39 + repoName := r.URL.Query().Get("repoName") 42 40 43 41 switch r.Method { 44 42 case http.MethodPost: ··· 83 81 IsStarred: true, 84 82 SubjectAt: subjectUri, 85 83 StarCount: starCount, 86 - StarsHref: starsHref, 84 + RepoName: repoName, 87 85 }) 88 86 89 87 return ··· 124 122 IsStarred: false, 125 123 SubjectAt: subjectUri, 126 124 StarCount: starCount, 127 - StarsHref: starsHref, 125 + RepoName: repoName, 128 126 }) 129 127 130 128 return ··· 132 130 133 131 } 134 132 135 - func (s *State) starsHref(ctx context.Context, subjectUri syntax.ATURI) string { 136 - repo, err := db.GetRepoByAtUri(s.db, subjectUri.String()) 137 - if err != nil { 138 - return "" 139 - } 140 - 141 - id, err := s.idResolver.ResolveIdent(ctx, repo.Did) 142 - if err != nil { 143 - return fmt.Sprintf("/%s/%s/stars", repo.Did, repo.Name) 144 - } 145 - 146 - return fmt.Sprintf("/%s/%s/stars", id.Handle, repo.Name) 147 - }

History

4 rounds 14 comments
sign up or login to add to the discussion
3 commits
expand
appview/db: add GetStarrers to list stargazers for a repo
appview: add "starred-by" page at /{user}/{repo}/stars
appview/pages: split star button to include starrers link
no conflicts, ready to merge
expand 0 comments
3 commits
expand
appview/db: add GetStarrers to list stargazers for a repo
appview: add "starred-by" page at /{user}/{repo}/stars
appview/pages: split star button to include starrers link
expand 6 comments
  • here we should use overview, since there is no stars tab
  • why do we need to pass StarsHref around? not saying we shouldn't, just curious!
  • i would like for this button to be styled more like the codeberg/github buttons, [icon "star" | count], where clicking on the count goes to the starred-by page, and clicking on the left portion performs the star creation/deletion action.

I think the difficulty with trying to style like codeberg is that it has distinctly different buttons for fork and view fork, and watch and view watchers, in addition to just stars and starrers. With how the buttons are set up currently on tangled, I'm not sure if it would make sense from a user's perspective if clicking on the number shows the starrers, since it visually looks like the same button as the star itself. (although maybe there is room to make a change, if you want to also add a fork count and "view forks" page.

GitHub also works a bit differently (although more similar to how this MR is set up). It treats the star button on a repo page as a star/unstar button, and requires clicking a different spot on the page to view who starred the repo (in the sidebar where it shows license, star and fork count etc.). Tangled doesn't exactly have an analog for this sidebar menu (but maybe there is room for a starrers section below where commits/branches are shown? -- I don't think it would make sense to need to scroll down to see this info though).

As for StarsHref, I made those functions to get the URL for the template, but I may have missed something so I'll take another pass to see if I can pull in the repo name and DID in a simpler way. (The lack of tooling for HTML templates does make this a bit tricky to poke at, so its quite possible I just missed something)

Dug in a bit more, I think it is necessary to get the repo name in order to populate the star page URL on the button. Also, I had an idea for the star button that I'll try later -- move the star count to where I have the new icon, and show "star" or "unstar" next to the star icon (basically just what codeberg does). If it looks good, but weird next to the other buttons I'll make a separate PR to make a similar change to the other buttons.

Okay, I was wrong, we can just pass .RepoName into the template, which removes the need for the StarsHref pattern. Latest version is a bit simpler, using a query param instead.

This isn't necessarily better since we need to add RepoName in a few places in the code, so I can revert this change if you'd rather keep the functions around instead.

3 commits
expand
appview/db: add GetStarrers to list stargazers for a repo
appview: add "starred-by" page at /{user}/{repo}/stars
appview/pages: split star button to include starrers link
expand 4 comments

Looks like the diff got bigger from a bunch of unrelated changes. None of those were changed in any of commits, do I just need to rebase?

*any of my commits

Yeah that's a bug from our implementation ๐Ÿ˜… Rebasing to master will fix it.

3 commits
expand
appview/db: add GetStarrers to list stargazers for a repo
appview: add "starred-by" page at /{user}/{repo}/stars
appview/pages: split star button to include starrers link
expand 4 comments

Also, screenshots of what this new page and the stars button look like can be seen in the tangled discord

Thank you for the contribution! As .StarsHref is pretty constant for the repository, can we generate it from star handlers instead of receiving as a url query?

Or we can just not include the surrounding div on add Star htmx api.

I like the idea of generating it from a handler, I'll implement that.