- gitea.GetRepo returns FullName + UpdatedAt for the stale-card probe - dashboard collectStale: mai-managed items + linked-repo updated_at >60d + zero open tasks + zero open issues. Sorted longest-stale first, ≤20. Multi-repo items need ALL repos quiet to count as stale. Reuses the 4-worker pool + the already-aggregated task/issue counts from the Tasks / Issues cards (no extra DAV/Gitea fetches). - dashboardCache.invalidate(key) busts a single filter's cache entry; ?refresh=1 routes through it so ↻ button gets fresh data. - "updated Nm ago · cached/fresh" label + ↻ refresh link in dashboard chrome. - Empty-card collapse: with no filter + zero rows the card renders as a one-line muted note instead of full chrome. Filter-active cards keep chrome so m can tell "filter hid it" from "nothing there". - design.md §"Dashboard / daily-driver view" extended with the 4 new surfaces; the 3e "stale (3f)" out-of-scope line dropped. - 5 new tests: stale-surface, stale-skip-recent, refresh-busts-cache, empty-collapse, filter-keeps-chrome. 2 unit tests for gitea.GetRepo.
41 lines
1.1 KiB
Go
41 lines
1.1 KiB
Go
package gitea
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// Repo is the slice of /repos/{owner}/{repo} projax cares about for the
|
|
// stale-projects dashboard card: the timestamp Gitea last touched the repo
|
|
// (commits, issues, releases all bump this).
|
|
type Repo struct {
|
|
FullName string // e.g. "m/projax"
|
|
UpdatedAt time.Time
|
|
Empty bool // freshly-created repo with no commits yet
|
|
}
|
|
|
|
type rawRepo struct {
|
|
FullName string `json:"full_name"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
Empty bool `json:"empty"`
|
|
}
|
|
|
|
// GetRepo fetches the repo's metadata. Returns ErrNotFound when the API
|
|
// returns 404 (repo renamed / deleted / token lacks access).
|
|
func (c *Client) GetRepo(ctx context.Context, owner, repo string) (*Repo, error) {
|
|
resp, err := c.do(ctx, "GET", "/repos/"+owner+"/"+repo, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != 200 {
|
|
return nil, readErr(resp, "get repo")
|
|
}
|
|
var r rawRepo
|
|
if err := json.NewDecoder(resp.Body).Decode(&r); err != nil {
|
|
return nil, err
|
|
}
|
|
return &Repo{FullName: r.FullName, UpdatedAt: r.UpdatedAt, Empty: r.Empty}, nil
|
|
}
|