From 4a5df81dac9eccd24bf9f6263ecf6ca7c7e5e33d Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Tue, 19 Aug 2025 11:26:06 +0300 Subject: [PATCH] appview/pages: show trending repos in the timeline Change-Id: zxovstvplnokulqzlusxlmokosyqzkqy Signed-off-by: Anirudh Oppiliappan --- appview/db/db.go | 4 + appview/db/star.go | 76 ++++++++++++++++++- appview/pages/pages.go | 11 ++- appview/pages/templates/layouts/base.html | 41 +++++++--- .../timeline/fragments/topStarredRepos.html | 65 ++++++++++++++++ .../templates/{ => timeline}/timeline.html | 27 ++++++- appview/state/router.go | 1 + appview/state/state.go | 13 ++++ 8 files changed, 221 insertions(+), 17 deletions(-) create mode 100644 appview/pages/templates/timeline/fragments/topStarredRepos.html rename appview/pages/templates/{ => timeline}/timeline.html (86%) diff --git a/appview/db/db.go b/appview/db/db.go index afb4fe95..45cafa30 100644 --- a/appview/db/db.go +++ b/appview/db/db.go @@ -470,6 +470,10 @@ func Make(dbPath string) (*DB, error) { id integer primary key autoincrement, name text unique ); + + -- indexes for better star query performance + create index if not exists idx_stars_created on stars(created); + create index if not exists idx_stars_repo_at_created on stars(repo_at, created); `) if err != nil { return nil, err diff --git a/appview/db/star.go b/appview/db/star.go index 7a005f3b..52c76a32 100644 --- a/appview/db/star.go +++ b/appview/db/star.go @@ -47,7 +47,7 @@ func AddStar(e Execer, star *Star) error { // Get a star record func GetStar(e Execer, starredByDid string, repoAt syntax.ATURI) (*Star, error) { query := ` - select starred_by_did, repo_at, created, rkey + select starred_by_did, repo_at, created, rkey from stars where starred_by_did = ? and repo_at = ?` row := e.QueryRow(query, starredByDid, repoAt) @@ -119,7 +119,7 @@ func GetStars(e Execer, limit int, filters ...filter) ([]Star, error) { } repoQuery := fmt.Sprintf( - `select starred_by_did, repo_at, created, rkey + `select starred_by_did, repo_at, created, rkey from stars %s order by created desc @@ -187,7 +187,7 @@ func GetAllStars(e Execer, limit int) ([]Star, error) { var stars []Star rows, err := e.Query(` - select + select s.starred_by_did, s.repo_at, s.rkey, @@ -244,3 +244,73 @@ func GetAllStars(e Execer, limit int) ([]Star, error) { return stars, nil } + +// GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week +func GetTopStarredReposLastWeek(e Execer) ([]Repo, error) { + // first, get the top repo URIs by star count from the last week + query := ` + with recent_starred_repos as ( + select distinct repo_at + from stars + where created >= datetime('now', '-7 days') + ), + repo_star_counts as ( + select + s.repo_at, + count(*) as star_count + from stars s + join recent_starred_repos rsr on s.repo_at = rsr.repo_at + where s.created >= datetime('now', '-7 days') + group by s.repo_at + ) + select rsc.repo_at + from repo_star_counts rsc + order by rsc.star_count desc + limit 8 + ` + + rows, err := e.Query(query) + if err != nil { + return nil, err + } + defer rows.Close() + + var repoUris []string + for rows.Next() { + var repoUri string + err := rows.Scan(&repoUri) + if err != nil { + return nil, err + } + repoUris = append(repoUris, repoUri) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + if len(repoUris) == 0 { + return []Repo{}, nil + } + + // get full repo data + repos, err := GetRepos(e, 0, FilterIn("at_uri", repoUris)) + if err != nil { + return nil, err + } + + // sort repos by the original trending order + repoMap := make(map[string]Repo) + for _, repo := range repos { + repoMap[repo.RepoAt().String()] = repo + } + + orderedRepos := make([]Repo, 0, len(repoUris)) + for _, uri := range repoUris { + if repo, exists := repoMap[uri]; exists { + orderedRepos = append(orderedRepos, repo) + } + } + + return orderedRepos, nil +} diff --git a/appview/pages/pages.go b/appview/pages/pages.go index 24c46689..93fa441b 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -302,7 +302,16 @@ type TimelineParams struct { } func (p *Pages) Timeline(w io.Writer, params TimelineParams) error { - return p.execute("timeline", w, params) + return p.execute("timeline/timeline", w, params) +} + +type TopStarredReposLastWeekParams struct { + LoggedInUser *oauth.User + Repos []db.Repo +} + +func (p *Pages) TopStarredReposLastWeek(w io.Writer, params TopStarredReposLastWeekParams) error { + return p.executePlain("timeline/fragments/topStarredRepos", w, params) } type SettingsParams struct { diff --git a/appview/pages/templates/layouts/base.html b/appview/pages/templates/layouts/base.html index 19e96de5..22f38b34 100644 --- a/appview/pages/templates/layouts/base.html +++ b/appview/pages/templates/layouts/base.html @@ -16,29 +16,52 @@ {{ block "topbarLayout" . }} -
+
{{ template "layouts/topbar" . }}
{{ end }} {{ block "mainLayout" . }} + +
+ {{ block "contentRight" . }} {{ end }} +
+
+ {{ block "contentLayout" . }} -
- {{ block "content" . }}{{ end }} -
+
+
+ {{ block "contentLeft" . }} {{ end }} +
+
+ {{ block "content" . }}{{ end }} +
+ + +
{{ end }} - + {{ block "contentAfterLayout" . }} -
- {{ block "contentAfter" . }}{{ end }} -
+
+
+ {{ block "contentAfterLeft" . }} {{ end }} +
+
+ {{ block "contentAfter" . }}{{ end }} +
+
+ {{ block "contentAfterRight" . }} {{ end }} +
+
{{ end }}
{{ end }} {{ block "footerLayout" . }} -