feat(basin): stars tab on profiles
4 files changed, +16 −5
- store.go modified +2 −2
- templates/stars.html added +7 −0
- templates/user.html modified +1 −2
- web.go modified +6 −1
store.go modified
| @@ -489,7 +489,7 @@ func (s *Store) UserByToken(name, token string) (User, bool) { | ||
| 489 | 489 | } |
| 490 | 490 | |
| 491 | 491 | func (s *Store) CreateRepo(owner User, name, description string, visibility int, rawTags string) (Repo, error) { |
| 492 | - if !validName(name) || name == "avatar" { | |
| 492 | + if !validName(name) || name == "avatar" || name == "stars" { | |
| 493 | 493 | return Repo{}, errors.New("Repository names are lowercase letters, digits, dot, dash or underscore") |
| 494 | 494 | } |
| 495 | 495 | tags, err := parseTags(rawTags) |
| @@ -861,7 +861,7 @@ func (s *Store) DeleteUser(name string) error { | ||
| 861 | 861 | } |
| 862 | 862 | |
| 863 | 863 | func (s *Store) RenameRepo(id int64, name string) error { |
| 864 | - if !validName(name) || name == "avatar" { | |
| 864 | + if !validName(name) || name == "avatar" || name == "stars" { | |
| 865 | 865 | return errors.New("Repository names are lowercase letters, digits, dot, dash or underscore") |
| 866 | 866 | } |
| 867 | 867 | _, err := s.db.Exec(`update repos set name = ? where id = ?`, name, id) |
templates/stars.html added
| @@ -0,0 +1,7 @@ | ||
| 1 | +{{define "content"}} | |
| 2 | +<div class="userhead"> | |
| 3 | +<h2>~{{.Data.Owner.Name}}</h2> | |
| 4 | +<nav class="tabs small"><a href="/~{{.Data.Owner.Name}}">about</a><a class="active" href="/~{{.Data.Owner.Name}}/stars">stars{{if .Data.Count}} <span class="count">{{.Data.Count}}</span>{{end}}</a></nav> | |
| 5 | +</div> | |
| 6 | +{{if .Data.Starred}}<div class="events">{{range .Data.Starred}}<div class="event"><h4><a href="/~{{.Owner.Name}}">~{{.Owner.Name}}</a>/<a href="/{{.Path}}">{{.Name}}</a></h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/projects?tag={{.}}">#{{.}}</a> {{end}}</p>{{end}}</div>{{end}}</div>{{else}}<p class="info">~{{.Data.Owner.Name}} has not starred anything yet.</p>{{end}} | |
| 7 | +{{end}} | |
templates/user.html modified
| @@ -3,7 +3,7 @@ | ||
| 3 | 3 | {{$own := and .User (eq .User.ID .Data.Owner.ID)}} |
| 4 | 4 | <div class="userhead"> |
| 5 | 5 | <h2>~{{.Data.Owner.Name}}</h2> |
| 6 | -<nav class="tabs small"><a class="active" href="/~{{.Data.Owner.Name}}">about</a></nav> | |
| 6 | +<nav class="tabs small"><a class="active" href="/~{{.Data.Owner.Name}}">about</a><a href="/~{{.Data.Owner.Name}}/stars">stars{{if .Data.Count}} <span class="count">{{.Data.Count}}</span>{{end}}</a></nav> | |
| 7 | 7 | </div> |
| 8 | 8 | <div class="columns user"> |
| 9 | 9 | <aside class="profile"> |
| @@ -17,7 +17,6 @@ | ||
| 17 | 17 | </aside> |
| 18 | 18 | <div class="main"> |
| 19 | 19 | {{if .Data.Repos}}<div class="events">{{range .Data.Repos}}<div class="event"><h4><a href="/{{.Path}}">{{.Name}}</a>{{if .Private}} <span class="tag">private</span>{{else if .Unlisted}} <span class="tag">unlisted</span>{{end}}</h4>{{if .Description}}<p>{{.Description}}</p>{{end}}{{if .Tags}}<p class="tags">{{range .Tags}}<a href="/projects?tag={{.}}">#{{.}}</a> {{end}}</p>{{end}}</div>{{end}}</div>{{else}}<p class="info">This user does not have any repositories.</p>{{end}} |
| 20 | -{{with .Data.Starred}}<h3 class="plain">Starred</h3><div class="events">{{range .}}<div class="event"><h4><a href="/{{.Path}}">{{.Path}}</a></h4>{{if .Description}}<p>{{.Description}}</p>{{end}}</div>{{end}}</div>{{end}} | |
| 21 | 20 | </div> |
| 22 | 21 | </div> |
| 23 | 22 | {{end}} |
web.go modified
| @@ -719,7 +719,7 @@ func (s *Server) route(w http.ResponseWriter, r *http.Request) { | ||
| 719 | 719 | bio = s.renderMarkdown([]byte(profile.Bio)) |
| 720 | 720 | } |
| 721 | 721 | starred, _ := s.store.StarredRepos(owner.ID) |
| 722 | - s.render(w, r, "user", page{Title: "~" + owner.Name, User: user, Math: hasMath(bio), Data: map[string]any{"Owner": owner, "Repos": repos, "Profile": profile, "Bio": bio, "Starred": starred}}) | |
| 722 | + s.render(w, r, "user", page{Title: "~" + owner.Name, User: user, Math: hasMath(bio), Data: map[string]any{"Owner": owner, "Repos": repos, "Profile": profile, "Bio": bio, "Count": len(starred)}}) | |
| 723 | 723 | return |
| 724 | 724 | } |
| 725 | 725 | name := parts[1] |
| @@ -727,6 +727,11 @@ func (s *Server) route(w http.ResponseWriter, r *http.Request) { | ||
| 727 | 727 | s.serveAvatar(w, r, owner) |
| 728 | 728 | return |
| 729 | 729 | } |
| 730 | + if name == "stars" && len(parts) == 2 && r.Method == "GET" { | |
| 731 | + starred, _ := s.store.StarredRepos(owner.ID) | |
| 732 | + s.render(w, r, "stars", page{Title: "~" + owner.Name + " stars", User: user, Data: map[string]any{"Owner": owner, "Starred": starred, "Count": len(starred)}}) | |
| 733 | + return | |
| 734 | + } | |
| 730 | 735 | rest := "" |
| 731 | 736 | if len(parts) == 3 { |
| 732 | 737 | rest = parts[2] |