+1
-1
appview/db/collaborators.go
+1
-1
appview/db/collaborators.go
+5
-10
appview/db/issues.go
+5
-10
appview/db/issues.go
···
32
// like comment counts, parent repo etc.
33
Comments []IssueComment
34
Labels models.LabelState
35
-
Repo *Repo
36
}
37
38
func (i *Issue) AtUri() syntax.ATURI {
···
376
return nil, fmt.Errorf("failed to build repo mappings: %w", err)
377
}
378
379
-
repoMap := make(map[string]*Repo)
380
for i := range repos {
381
repoMap[string(repos[i].RepoAt())] = &repos[i]
382
}
···
658
return err
659
}
660
661
-
type IssueCount struct {
662
-
Open int
663
-
Closed int
664
-
}
665
-
666
-
func GetIssueCount(e Execer, repoAt syntax.ATURI) (IssueCount, error) {
667
row := e.QueryRow(`
668
select
669
count(case when open = 1 then 1 end) as open_count,
···
673
repoAt,
674
)
675
676
-
var count IssueCount
677
if err := row.Scan(&count.Open, &count.Closed); err != nil {
678
-
return IssueCount{0, 0}, err
679
}
680
681
return count, nil
···
32
// like comment counts, parent repo etc.
33
Comments []IssueComment
34
Labels models.LabelState
35
+
Repo *models.Repo
36
}
37
38
func (i *Issue) AtUri() syntax.ATURI {
···
376
return nil, fmt.Errorf("failed to build repo mappings: %w", err)
377
}
378
379
+
repoMap := make(map[string]*models.Repo)
380
for i := range repos {
381
repoMap[string(repos[i].RepoAt())] = &repos[i]
382
}
···
658
return err
659
}
660
661
+
func GetIssueCount(e Execer, repoAt syntax.ATURI) (models.IssueCount, error) {
662
row := e.QueryRow(`
663
select
664
count(case when open = 1 then 1 end) as open_count,
···
668
repoAt,
669
)
670
671
+
var count models.IssueCount
672
if err := row.Scan(&count.Open, &count.Closed); err != nil {
673
+
return models.IssueCount{0, 0}, err
674
}
675
676
return count, nil
+4
-3
appview/db/profile.go
+4
-3
appview/db/profile.go
···
11
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
"tangled.org/core/api/tangled"
14
)
15
16
type RepoEvent struct {
17
-
Repo *Repo
18
-
Source *Repo
19
}
20
21
type ProfileTimeline struct {
···
162
163
for _, repo := range repos {
164
// TODO: get this in the original query; requires COALESCE because nullable
165
-
var sourceRepo *Repo
166
if repo.Source != "" {
167
sourceRepo, err = GetRepoByAtUri(e, repo.Source)
168
if err != nil {
···
11
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
"tangled.org/core/api/tangled"
14
+
"tangled.org/core/appview/models"
15
)
16
17
type RepoEvent struct {
18
+
Repo *models.Repo
19
+
Source *models.Repo
20
}
21
22
type ProfileTimeline struct {
···
163
164
for _, repo := range repos {
165
// TODO: get this in the original query; requires COALESCE because nullable
166
+
var sourceRepo *models.Repo
167
if repo.Source != "" {
168
sourceRepo, err = GetRepoByAtUri(e, repo.Source)
169
if err != nil {
+8
-14
appview/db/pulls.go
+8
-14
appview/db/pulls.go
···
11
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
"tangled.org/core/api/tangled"
14
"tangled.org/core/patchutil"
15
"tangled.org/core/types"
16
)
···
79
PullSource *PullSource
80
81
// optionally, populate this when querying for reverse mappings
82
-
Repo *Repo
83
}
84
85
func (p Pull) AsRecord() tangled.RepoPull {
···
109
RepoAt *syntax.ATURI
110
111
// optionally populate this for reverse mappings
112
-
Repo *Repo
113
}
114
115
func (p PullSource) AsRecord() tangled.RepoPull_Source {
···
723
return nil, err
724
}
725
726
-
var pullSourceRepo *Repo
727
if pull.PullSource != nil {
728
if pull.PullSource.RepoAt != nil {
729
pullSourceRepo, err = GetRepoByAtUri(e, pull.PullSource.RepoAt.String())
···
776
777
for rows.Next() {
778
var pull Pull
779
-
var repo Repo
780
var pullCreatedAt, repoCreatedAt string
781
err := rows.Scan(
782
&pull.OwnerDid,
···
931
return err
932
}
933
934
-
type PullCount struct {
935
-
Open int
936
-
Merged int
937
-
Closed int
938
-
Deleted int
939
-
}
940
-
941
-
func GetPullCount(e Execer, repoAt syntax.ATURI) (PullCount, error) {
942
row := e.QueryRow(`
943
select
944
count(case when state = ? then 1 end) as open_count,
···
954
repoAt,
955
)
956
957
-
var count PullCount
958
if err := row.Scan(&count.Open, &count.Merged, &count.Closed, &count.Deleted); err != nil {
959
-
return PullCount{0, 0, 0, 0}, err
960
}
961
962
return count, nil
···
11
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
"tangled.org/core/api/tangled"
14
+
"tangled.org/core/appview/models"
15
"tangled.org/core/patchutil"
16
"tangled.org/core/types"
17
)
···
80
PullSource *PullSource
81
82
// optionally, populate this when querying for reverse mappings
83
+
Repo *models.Repo
84
}
85
86
func (p Pull) AsRecord() tangled.RepoPull {
···
110
RepoAt *syntax.ATURI
111
112
// optionally populate this for reverse mappings
113
+
Repo *models.Repo
114
}
115
116
func (p PullSource) AsRecord() tangled.RepoPull_Source {
···
724
return nil, err
725
}
726
727
+
var pullSourceRepo *models.Repo
728
if pull.PullSource != nil {
729
if pull.PullSource.RepoAt != nil {
730
pullSourceRepo, err = GetRepoByAtUri(e, pull.PullSource.RepoAt.String())
···
777
778
for rows.Next() {
779
var pull Pull
780
+
var repo models.Repo
781
var pullCreatedAt, repoCreatedAt string
782
err := rows.Scan(
783
&pull.OwnerDid,
···
932
return err
933
}
934
935
+
func GetPullCount(e Execer, repoAt syntax.ATURI) (models.PullCount, error) {
936
row := e.QueryRow(`
937
select
938
count(case when state = ? then 1 end) as open_count,
···
948
repoAt,
949
)
950
951
+
var count models.PullCount
952
if err := row.Scan(&count.Open, &count.Merged, &count.Closed, &count.Deleted); err != nil {
953
+
return models.PullCount{Open: 0, Merged: 0, Closed: 0, Deleted: 0}, err
954
}
955
956
return count, nil
+20
-86
appview/db/repos.go
+20
-86
appview/db/repos.go
···
10
"time"
11
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
-
securejoin "github.com/cyphar/filepath-securejoin"
14
-
"tangled.org/core/api/tangled"
15
)
16
17
-
type Repo struct {
18
-
Did string
19
-
Name string
20
-
Knot string
21
-
Rkey string
22
-
Created time.Time
23
-
Description string
24
-
Spindle string
25
-
Labels []string
26
-
27
-
// optionally, populate this when querying for reverse mappings
28
-
RepoStats *RepoStats
29
-
30
-
// optional
31
-
Source string
32
-
}
33
-
34
-
func (r *Repo) AsRecord() tangled.Repo {
35
-
var source, spindle, description *string
36
-
37
-
if r.Source != "" {
38
-
source = &r.Source
39
-
}
40
-
41
-
if r.Spindle != "" {
42
-
spindle = &r.Spindle
43
-
}
44
-
45
-
if r.Description != "" {
46
-
description = &r.Description
47
-
}
48
-
49
-
return tangled.Repo{
50
-
Knot: r.Knot,
51
-
Name: r.Name,
52
-
Description: description,
53
-
CreatedAt: r.Created.Format(time.RFC3339),
54
-
Source: source,
55
-
Spindle: spindle,
56
-
Labels: r.Labels,
57
-
}
58
-
}
59
-
60
-
func (r Repo) RepoAt() syntax.ATURI {
61
-
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", r.Did, tangled.RepoNSID, r.Rkey))
62
-
}
63
-
64
-
func (r Repo) DidSlashRepo() string {
65
-
p, _ := securejoin.SecureJoin(r.Did, r.Name)
66
-
return p
67
-
}
68
-
69
-
func GetRepos(e Execer, limit int, filters ...filter) ([]Repo, error) {
70
-
repoMap := make(map[syntax.ATURI]*Repo)
71
72
var conditions []string
73
var args []any
···
111
}
112
113
for rows.Next() {
114
-
var repo Repo
115
var createdAt string
116
var description, source, spindle sql.NullString
117
···
142
repo.Spindle = spindle.String
143
}
144
145
-
repo.RepoStats = &RepoStats{}
146
repoMap[repo.RepoAt()] = &repo
147
}
148
···
320
return nil, fmt.Errorf("failed to execute pulls-count query: %w ", err)
321
}
322
323
-
var repos []Repo
324
for _, r := range repoMap {
325
repos = append(repos, *r)
326
}
327
328
-
slices.SortFunc(repos, func(a, b Repo) int {
329
if a.Created.After(b.Created) {
330
return -1
331
}
···
336
}
337
338
// helper to get exactly one repo
339
-
func GetRepo(e Execer, filters ...filter) (*Repo, error) {
340
repos, err := GetRepos(e, 0, filters...)
341
if err != nil {
342
return nil, err
···
377
return count, nil
378
}
379
380
-
func GetRepoByAtUri(e Execer, atUri string) (*Repo, error) {
381
-
var repo Repo
382
var nullableDescription sql.NullString
383
384
row := e.QueryRow(`select did, name, knot, created, rkey, description from repos where at_uri = ?`, atUri)
···
399
return &repo, nil
400
}
401
402
-
func AddRepo(e Execer, repo *Repo) error {
403
_, err := e.Exec(
404
`insert into repos
405
(did, name, knot, rkey, at_uri, description, source)
···
423
return nullableSource.String, nil
424
}
425
426
-
func GetForksByDid(e Execer, did string) ([]Repo, error) {
427
-
var repos []Repo
428
429
rows, err := e.Query(
430
`select distinct r.did, r.name, r.knot, r.rkey, r.description, r.created, r.source
···
442
defer rows.Close()
443
444
for rows.Next() {
445
-
var repo Repo
446
var createdAt string
447
var nullableDescription sql.NullString
448
var nullableSource sql.NullString
···
477
return repos, nil
478
}
479
480
-
func GetForkByDid(e Execer, did string, name string) (*Repo, error) {
481
-
var repo Repo
482
var createdAt string
483
var nullableDescription sql.NullString
484
var nullableSource sql.NullString
···
525
return err
526
}
527
528
-
type RepoStats struct {
529
-
Language string
530
-
StarCount int
531
-
IssueCount IssueCount
532
-
PullCount PullCount
533
-
}
534
-
535
-
type RepoLabel struct {
536
-
Id int64
537
-
RepoAt syntax.ATURI
538
-
LabelAt syntax.ATURI
539
-
}
540
-
541
-
func SubscribeLabel(e Execer, rl *RepoLabel) error {
542
query := `insert or ignore into repo_labels (repo_at, label_at) values (?, ?)`
543
544
_, err := e.Exec(query, rl.RepoAt.String(), rl.LabelAt.String())
···
563
return err
564
}
565
566
-
func GetRepoLabels(e Execer, filters ...filter) ([]RepoLabel, error) {
567
var conditions []string
568
var args []any
569
for _, filter := range filters {
···
584
}
585
defer rows.Close()
586
587
-
var labels []RepoLabel
588
for rows.Next() {
589
-
var label RepoLabel
590
591
err := rows.Scan(&label.Id, &label.RepoAt, &label.LabelAt)
592
if err != nil {
···
10
"time"
11
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
+
"tangled.org/core/appview/models"
14
)
15
16
+
func GetRepos(e Execer, limit int, filters ...filter) ([]models.Repo, error) {
17
+
repoMap := make(map[syntax.ATURI]*models.Repo)
18
19
var conditions []string
20
var args []any
···
58
}
59
60
for rows.Next() {
61
+
var repo models.Repo
62
var createdAt string
63
var description, source, spindle sql.NullString
64
···
89
repo.Spindle = spindle.String
90
}
91
92
+
repo.RepoStats = &models.RepoStats{}
93
repoMap[repo.RepoAt()] = &repo
94
}
95
···
267
return nil, fmt.Errorf("failed to execute pulls-count query: %w ", err)
268
}
269
270
+
var repos []models.Repo
271
for _, r := range repoMap {
272
repos = append(repos, *r)
273
}
274
275
+
slices.SortFunc(repos, func(a, b models.Repo) int {
276
if a.Created.After(b.Created) {
277
return -1
278
}
···
283
}
284
285
// helper to get exactly one repo
286
+
func GetRepo(e Execer, filters ...filter) (*models.Repo, error) {
287
repos, err := GetRepos(e, 0, filters...)
288
if err != nil {
289
return nil, err
···
324
return count, nil
325
}
326
327
+
func GetRepoByAtUri(e Execer, atUri string) (*models.Repo, error) {
328
+
var repo models.Repo
329
var nullableDescription sql.NullString
330
331
row := e.QueryRow(`select did, name, knot, created, rkey, description from repos where at_uri = ?`, atUri)
···
346
return &repo, nil
347
}
348
349
+
func AddRepo(e Execer, repo *models.Repo) error {
350
_, err := e.Exec(
351
`insert into repos
352
(did, name, knot, rkey, at_uri, description, source)
···
370
return nullableSource.String, nil
371
}
372
373
+
func GetForksByDid(e Execer, did string) ([]models.Repo, error) {
374
+
var repos []models.Repo
375
376
rows, err := e.Query(
377
`select distinct r.did, r.name, r.knot, r.rkey, r.description, r.created, r.source
···
389
defer rows.Close()
390
391
for rows.Next() {
392
+
var repo models.Repo
393
var createdAt string
394
var nullableDescription sql.NullString
395
var nullableSource sql.NullString
···
424
return repos, nil
425
}
426
427
+
func GetForkByDid(e Execer, did string, name string) (*models.Repo, error) {
428
+
var repo models.Repo
429
var createdAt string
430
var nullableDescription sql.NullString
431
var nullableSource sql.NullString
···
472
return err
473
}
474
475
+
func SubscribeLabel(e Execer, rl *models.RepoLabel) error {
476
query := `insert or ignore into repo_labels (repo_at, label_at) values (?, ?)`
477
478
_, err := e.Exec(query, rl.RepoAt.String(), rl.LabelAt.String())
···
497
return err
498
}
499
500
+
func GetRepoLabels(e Execer, filters ...filter) ([]models.RepoLabel, error) {
501
var conditions []string
502
var args []any
503
for _, filter := range filters {
···
518
}
519
defer rows.Close()
520
521
+
var labels []models.RepoLabel
522
for rows.Next() {
523
+
var label models.RepoLabel
524
525
err := rows.Scan(&label.Id, &label.RepoAt, &label.LabelAt)
526
if err != nil {
+7
-6
appview/db/star.go
+7
-6
appview/db/star.go
···
9
"time"
10
11
"github.com/bluesky-social/indigo/atproto/syntax"
12
)
13
14
type Star struct {
···
18
Rkey string
19
20
// optionally, populate this when querying for reverse mappings
21
-
Repo *Repo
22
}
23
24
func (star *Star) ResolveRepo(e Execer) error {
···
284
285
for rows.Next() {
286
var star Star
287
-
var repo Repo
288
var starCreatedAt, repoCreatedAt string
289
290
if err := rows.Scan(
···
322
}
323
324
// GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week
325
-
func GetTopStarredReposLastWeek(e Execer) ([]Repo, error) {
326
// first, get the top repo URIs by star count from the last week
327
query := `
328
with recent_starred_repos as (
···
366
}
367
368
if len(repoUris) == 0 {
369
-
return []Repo{}, nil
370
}
371
372
// get full repo data
···
376
}
377
378
// sort repos by the original trending order
379
-
repoMap := make(map[string]Repo)
380
for _, repo := range repos {
381
repoMap[repo.RepoAt().String()] = repo
382
}
383
384
-
orderedRepos := make([]Repo, 0, len(repoUris))
385
for _, uri := range repoUris {
386
if repo, exists := repoMap[uri]; exists {
387
orderedRepos = append(orderedRepos, repo)
···
9
"time"
10
11
"github.com/bluesky-social/indigo/atproto/syntax"
12
+
"tangled.org/core/appview/models"
13
)
14
15
type Star struct {
···
19
Rkey string
20
21
// optionally, populate this when querying for reverse mappings
22
+
Repo *models.Repo
23
}
24
25
func (star *Star) ResolveRepo(e Execer) error {
···
285
286
for rows.Next() {
287
var star Star
288
+
var repo models.Repo
289
var starCreatedAt, repoCreatedAt string
290
291
if err := rows.Scan(
···
323
}
324
325
// GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week
326
+
func GetTopStarredReposLastWeek(e Execer) ([]models.Repo, error) {
327
// first, get the top repo URIs by star count from the last week
328
query := `
329
with recent_starred_repos as (
···
367
}
368
369
if len(repoUris) == 0 {
370
+
return []models.Repo{}, nil
371
}
372
373
// get full repo data
···
377
}
378
379
// sort repos by the original trending order
380
+
repoMap := make(map[string]models.Repo)
381
for _, repo := range repos {
382
repoMap[repo.RepoAt().String()] = repo
383
}
384
385
+
orderedRepos := make([]models.Repo, 0, len(repoUris))
386
for _, uri := range repoUris {
387
if repo, exists := repoMap[uri]; exists {
388
orderedRepos = append(orderedRepos, repo)
+8
-8
appview/db/timeline.go
+8
-8
appview/db/timeline.go
···
9
)
10
11
type TimelineEvent struct {
12
-
*Repo
13
*models.Follow
14
*Star
15
16
EventAt time.Time
17
18
// optional: populate only if Repo is a fork
19
-
Source *Repo
20
21
// optional: populate only if event is Follow
22
*Profile
···
64
return events, nil
65
}
66
67
-
func fetchStarStatuses(e Execer, loggedInUserDid string, repos []Repo) (map[string]bool, error) {
68
if loggedInUserDid == "" {
69
return nil, nil
70
}
···
77
return GetStarStatuses(e, loggedInUserDid, repoAts)
78
}
79
80
-
func getRepoStarInfo(repo *Repo, starStatuses map[string]bool) (bool, int64) {
81
var isStarred bool
82
if starStatuses != nil {
83
isStarred = starStatuses[repo.RepoAt().String()]
···
105
}
106
}
107
108
-
var origRepos []Repo
109
if args != nil {
110
origRepos, err = GetRepos(e, 0, FilterIn("at_uri", args))
111
}
···
113
return nil, err
114
}
115
116
-
uriToRepo := make(map[string]Repo)
117
for _, r := range origRepos {
118
uriToRepo[r.RepoAt().String()] = r
119
}
···
125
126
var events []TimelineEvent
127
for _, r := range repos {
128
-
var source *Repo
129
if r.Source != "" {
130
if origRepo, ok := uriToRepo[r.Source]; ok {
131
source = &origRepo
···
162
}
163
stars = stars[:n]
164
165
-
var repos []Repo
166
for _, s := range stars {
167
repos = append(repos, *s.Repo)
168
}
···
9
)
10
11
type TimelineEvent struct {
12
+
*models.Repo
13
*models.Follow
14
*Star
15
16
EventAt time.Time
17
18
// optional: populate only if Repo is a fork
19
+
Source *models.Repo
20
21
// optional: populate only if event is Follow
22
*Profile
···
64
return events, nil
65
}
66
67
+
func fetchStarStatuses(e Execer, loggedInUserDid string, repos []models.Repo) (map[string]bool, error) {
68
if loggedInUserDid == "" {
69
return nil, nil
70
}
···
77
return GetStarStatuses(e, loggedInUserDid, repoAts)
78
}
79
80
+
func getRepoStarInfo(repo *models.Repo, starStatuses map[string]bool) (bool, int64) {
81
var isStarred bool
82
if starStatuses != nil {
83
isStarred = starStatuses[repo.RepoAt().String()]
···
105
}
106
}
107
108
+
var origRepos []models.Repo
109
if args != nil {
110
origRepos, err = GetRepos(e, 0, FilterIn("at_uri", args))
111
}
···
113
return nil, err
114
}
115
116
+
uriToRepo := make(map[string]models.Repo)
117
for _, r := range origRepos {
118
uriToRepo[r.RepoAt().String()] = r
119
}
···
125
126
var events []TimelineEvent
127
for _, r := range repos {
128
+
var source *models.Repo
129
if r.Source != "" {
130
if origRepo, ok := uriToRepo[r.Source]; ok {
131
source = &origRepo
···
162
}
163
stars = stars[:n]
164
165
+
var repos []models.Repo
166
for _, s := range stars {
167
repos = append(repos, *s.Repo)
168
}
+2
-1
appview/knots/knots.go
+2
-1
appview/knots/knots.go
···
13
"tangled.org/core/appview/config"
14
"tangled.org/core/appview/db"
15
"tangled.org/core/appview/middleware"
16
"tangled.org/core/appview/oauth"
17
"tangled.org/core/appview/pages"
18
"tangled.org/core/appview/serververify"
···
119
}
120
121
// organize repos by did
122
-
repoMap := make(map[string][]db.Repo)
123
for _, r := range repos {
124
repoMap[r.Did] = append(repoMap[r.Did], r)
125
}
···
13
"tangled.org/core/appview/config"
14
"tangled.org/core/appview/db"
15
"tangled.org/core/appview/middleware"
16
+
"tangled.org/core/appview/models"
17
"tangled.org/core/appview/oauth"
18
"tangled.org/core/appview/pages"
19
"tangled.org/core/appview/serververify"
···
120
}
121
122
// organize repos by did
123
+
repoMap := make(map[string][]models.Repo)
124
for _, r := range repos {
125
repoMap[r.Did] = append(repoMap[r.Did], r)
126
}
+87
appview/models/repo.go
+87
appview/models/repo.go
···
···
1
+
package models
2
+
3
+
import (
4
+
"fmt"
5
+
"time"
6
+
7
+
"github.com/bluesky-social/indigo/atproto/syntax"
8
+
securejoin "github.com/cyphar/filepath-securejoin"
9
+
"tangled.org/core/api/tangled"
10
+
)
11
+
12
+
type Repo struct {
13
+
Did string
14
+
Name string
15
+
Knot string
16
+
Rkey string
17
+
Created time.Time
18
+
Description string
19
+
Spindle string
20
+
Labels []string
21
+
22
+
// optionally, populate this when querying for reverse mappings
23
+
RepoStats *RepoStats
24
+
25
+
// optional
26
+
Source string
27
+
}
28
+
29
+
func (r *Repo) AsRecord() tangled.Repo {
30
+
var source, spindle, description *string
31
+
32
+
if r.Source != "" {
33
+
source = &r.Source
34
+
}
35
+
36
+
if r.Spindle != "" {
37
+
spindle = &r.Spindle
38
+
}
39
+
40
+
if r.Description != "" {
41
+
description = &r.Description
42
+
}
43
+
44
+
return tangled.Repo{
45
+
Knot: r.Knot,
46
+
Name: r.Name,
47
+
Description: description,
48
+
CreatedAt: r.Created.Format(time.RFC3339),
49
+
Source: source,
50
+
Spindle: spindle,
51
+
Labels: r.Labels,
52
+
}
53
+
}
54
+
55
+
func (r Repo) RepoAt() syntax.ATURI {
56
+
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", r.Did, tangled.RepoNSID, r.Rkey))
57
+
}
58
+
59
+
func (r Repo) DidSlashRepo() string {
60
+
p, _ := securejoin.SecureJoin(r.Did, r.Name)
61
+
return p
62
+
}
63
+
64
+
type RepoStats struct {
65
+
Language string
66
+
StarCount int
67
+
IssueCount IssueCount
68
+
PullCount PullCount
69
+
}
70
+
71
+
type IssueCount struct {
72
+
Open int
73
+
Closed int
74
+
}
75
+
76
+
type PullCount struct {
77
+
Open int
78
+
Merged int
79
+
Closed int
80
+
Deleted int
81
+
}
82
+
83
+
type RepoLabel struct {
84
+
Id int64
85
+
RepoAt syntax.ATURI
86
+
LabelAt syntax.ATURI
87
+
}
+1
-1
appview/notify/merged_notifier.go
+1
-1
appview/notify/merged_notifier.go
+2
-2
appview/notify/notifier.go
+2
-2
appview/notify/notifier.go
···
8
)
9
10
type Notifier interface {
11
-
NewRepo(ctx context.Context, repo *db.Repo)
12
13
NewStar(ctx context.Context, star *db.Star)
14
DeleteStar(ctx context.Context, star *db.Star)
···
33
34
var _ Notifier = &BaseNotifier{}
35
36
-
func (m *BaseNotifier) NewRepo(ctx context.Context, repo *db.Repo) {}
37
38
func (m *BaseNotifier) NewStar(ctx context.Context, star *db.Star) {}
39
func (m *BaseNotifier) DeleteStar(ctx context.Context, star *db.Star) {}
···
8
)
9
10
type Notifier interface {
11
+
NewRepo(ctx context.Context, repo *models.Repo)
12
13
NewStar(ctx context.Context, star *db.Star)
14
DeleteStar(ctx context.Context, star *db.Star)
···
33
34
var _ Notifier = &BaseNotifier{}
35
36
+
func (m *BaseNotifier) NewRepo(ctx context.Context, repo *models.Repo) {}
37
38
func (m *BaseNotifier) NewStar(ctx context.Context, star *db.Star) {}
39
func (m *BaseNotifier) DeleteStar(ctx context.Context, star *db.Star) {}
+12
-12
appview/pages/pages.go
+12
-12
appview/pages/pages.go
···
284
type TimelineParams struct {
285
LoggedInUser *oauth.User
286
Timeline []db.TimelineEvent
287
-
Repos []db.Repo
288
}
289
290
func (p *Pages) Timeline(w io.Writer, params TimelineParams) error {
···
345
LoggedInUser *oauth.User
346
Registration *db.Registration
347
Members []string
348
-
Repos map[string][]db.Repo
349
IsOwner bool
350
}
351
···
382
LoggedInUser *oauth.User
383
Spindle db.Spindle
384
Members []string
385
-
Repos map[string][]db.Repo
386
}
387
388
func (p *Pages) SpindleDashboard(w io.Writer, params SpindleDashboardParams) error {
···
439
440
type ProfileOverviewParams struct {
441
LoggedInUser *oauth.User
442
-
Repos []db.Repo
443
-
CollaboratingRepos []db.Repo
444
ProfileTimeline *db.ProfileTimeline
445
Card *ProfileCard
446
Active string
···
453
454
type ProfileReposParams struct {
455
LoggedInUser *oauth.User
456
-
Repos []db.Repo
457
Card *ProfileCard
458
Active string
459
}
···
465
466
type ProfileStarredParams struct {
467
LoggedInUser *oauth.User
468
-
Repos []db.Repo
469
Card *ProfileCard
470
Active string
471
}
···
545
546
type PinnedRepo struct {
547
IsPinned bool
548
-
db.Repo
549
}
550
551
func (p *Pages) EditPinsFragment(w io.Writer, params EditPinsParams) error {
···
555
type RepoStarFragmentParams struct {
556
IsStarred bool
557
RepoAt syntax.ATURI
558
-
Stats db.RepoStats
559
}
560
561
func (p *Pages) RepoStarFragment(w io.Writer, params RepoStarFragmentParams) error {
···
1122
1123
type PullCompareForkParams struct {
1124
RepoInfo repoinfo.RepoInfo
1125
-
Forks []db.Repo
1126
Selected string
1127
}
1128
···
1179
type RepoCompareParams struct {
1180
LoggedInUser *oauth.User
1181
RepoInfo repoinfo.RepoInfo
1182
-
Forks []db.Repo
1183
Branches []types.Branch
1184
Tags []*types.TagReference
1185
Base string
···
1198
type RepoCompareNewParams struct {
1199
LoggedInUser *oauth.User
1200
RepoInfo repoinfo.RepoInfo
1201
-
Forks []db.Repo
1202
Branches []types.Branch
1203
Tags []*types.TagReference
1204
Base string
···
284
type TimelineParams struct {
285
LoggedInUser *oauth.User
286
Timeline []db.TimelineEvent
287
+
Repos []models.Repo
288
}
289
290
func (p *Pages) Timeline(w io.Writer, params TimelineParams) error {
···
345
LoggedInUser *oauth.User
346
Registration *db.Registration
347
Members []string
348
+
Repos map[string][]models.Repo
349
IsOwner bool
350
}
351
···
382
LoggedInUser *oauth.User
383
Spindle db.Spindle
384
Members []string
385
+
Repos map[string][]models.Repo
386
}
387
388
func (p *Pages) SpindleDashboard(w io.Writer, params SpindleDashboardParams) error {
···
439
440
type ProfileOverviewParams struct {
441
LoggedInUser *oauth.User
442
+
Repos []models.Repo
443
+
CollaboratingRepos []models.Repo
444
ProfileTimeline *db.ProfileTimeline
445
Card *ProfileCard
446
Active string
···
453
454
type ProfileReposParams struct {
455
LoggedInUser *oauth.User
456
+
Repos []models.Repo
457
Card *ProfileCard
458
Active string
459
}
···
465
466
type ProfileStarredParams struct {
467
LoggedInUser *oauth.User
468
+
Repos []models.Repo
469
Card *ProfileCard
470
Active string
471
}
···
545
546
type PinnedRepo struct {
547
IsPinned bool
548
+
models.Repo
549
}
550
551
func (p *Pages) EditPinsFragment(w io.Writer, params EditPinsParams) error {
···
555
type RepoStarFragmentParams struct {
556
IsStarred bool
557
RepoAt syntax.ATURI
558
+
Stats models.RepoStats
559
}
560
561
func (p *Pages) RepoStarFragment(w io.Writer, params RepoStarFragmentParams) error {
···
1122
1123
type PullCompareForkParams struct {
1124
RepoInfo repoinfo.RepoInfo
1125
+
Forks []models.Repo
1126
Selected string
1127
}
1128
···
1179
type RepoCompareParams struct {
1180
LoggedInUser *oauth.User
1181
RepoInfo repoinfo.RepoInfo
1182
+
Forks []models.Repo
1183
Branches []types.Branch
1184
Tags []*types.TagReference
1185
Base string
···
1198
type RepoCompareNewParams struct {
1199
LoggedInUser *oauth.User
1200
RepoInfo repoinfo.RepoInfo
1201
+
Forks []models.Repo
1202
Branches []types.Branch
1203
Tags []*types.TagReference
1204
Base string
+3
-3
appview/pages/repoinfo/repoinfo.go
+3
-3
appview/pages/repoinfo/repoinfo.go
···
7
"strings"
8
9
"github.com/bluesky-social/indigo/atproto/syntax"
10
-
"tangled.org/core/appview/db"
11
"tangled.org/core/appview/state/userutil"
12
)
13
···
60
Spindle string
61
RepoAt syntax.ATURI
62
IsStarred bool
63
-
Stats db.RepoStats
64
Roles RolesInRepo
65
-
Source *db.Repo
66
SourceHandle string
67
Ref string
68
DisableFork bool
···
7
"strings"
8
9
"github.com/bluesky-social/indigo/atproto/syntax"
10
+
"tangled.org/core/appview/models"
11
"tangled.org/core/appview/state/userutil"
12
)
13
···
60
Spindle string
61
RepoAt syntax.ATURI
62
IsStarred bool
63
+
Stats models.RepoStats
64
Roles RolesInRepo
65
+
Source *models.Repo
66
SourceHandle string
67
Ref string
68
DisableFork bool
+1
-1
appview/posthog/notifier.go
+1
-1
appview/posthog/notifier.go
+2
-1
appview/pulls/pulls.go
+2
-1
appview/pulls/pulls.go
···
15
"tangled.org/core/api/tangled"
16
"tangled.org/core/appview/config"
17
"tangled.org/core/appview/db"
18
"tangled.org/core/appview/notify"
19
"tangled.org/core/appview/oauth"
20
"tangled.org/core/appview/pages"
···
500
}
501
502
for _, p := range pulls {
503
-
var pullSourceRepo *db.Repo
504
if p.PullSource != nil {
505
if p.PullSource.RepoAt != nil {
506
pullSourceRepo, err = db.GetRepoByAtUri(s.db, p.PullSource.RepoAt.String())
···
15
"tangled.org/core/api/tangled"
16
"tangled.org/core/appview/config"
17
"tangled.org/core/appview/db"
18
+
"tangled.org/core/appview/models"
19
"tangled.org/core/appview/notify"
20
"tangled.org/core/appview/oauth"
21
"tangled.org/core/appview/pages"
···
501
}
502
503
for _, p := range pulls {
504
+
var pullSourceRepo *models.Repo
505
if p.PullSource != nil {
506
if p.PullSource.RepoAt != nil {
507
pullSourceRepo, err = db.GetRepoByAtUri(s.db, p.PullSource.RepoAt.String())
+3
-3
appview/repo/repo.go
+3
-3
appview/repo/repo.go
···
1110
return
1111
}
1112
1113
-
err = db.SubscribeLabel(tx, &db.RepoLabel{
1114
RepoAt: f.RepoAt(),
1115
LabelAt: label.AtUri(),
1116
})
···
1286
},
1287
})
1288
1289
-
err = db.SubscribeLabel(rp.db, &db.RepoLabel{
1290
RepoAt: f.RepoAt(),
1291
LabelAt: syntax.ATURI(labelAt),
1292
})
···
2142
2143
// create an atproto record for this fork
2144
rkey := tid.TID()
2145
-
repo := &db.Repo{
2146
Did: user.Did,
2147
Name: forkName,
2148
Knot: targetKnot,
···
1110
return
1111
}
1112
1113
+
err = db.SubscribeLabel(tx, &models.RepoLabel{
1114
RepoAt: f.RepoAt(),
1115
LabelAt: label.AtUri(),
1116
})
···
1286
},
1287
})
1288
1289
+
err = db.SubscribeLabel(rp.db, &models.RepoLabel{
1290
RepoAt: f.RepoAt(),
1291
LabelAt: syntax.ATURI(labelAt),
1292
})
···
2142
2143
// create an atproto record for this fork
2144
rkey := tid.TID()
2145
+
repo := &models.Repo{
2146
Did: user.Did,
2147
Name: forkName,
2148
Knot: targetKnot,
+5
-4
appview/reporesolver/resolver.go
+5
-4
appview/reporesolver/resolver.go
···
16
"github.com/go-chi/chi/v5"
17
"tangled.org/core/appview/config"
18
"tangled.org/core/appview/db"
19
"tangled.org/core/appview/oauth"
20
"tangled.org/core/appview/pages"
21
"tangled.org/core/appview/pages/repoinfo"
···
24
)
25
26
type ResolvedRepo struct {
27
-
db.Repo
28
OwnerId identity.Identity
29
CurrentDir string
30
Ref string
···
44
}
45
46
func (rr *RepoResolver) Resolve(r *http.Request) (*ResolvedRepo, error) {
47
-
repo, ok := r.Context().Value("repo").(*db.Repo)
48
if !ok {
49
log.Println("malformed middleware: `repo` not exist in context")
50
return nil, fmt.Errorf("malformed middleware")
···
162
log.Println("failed to get repo source for ", repoAt, err)
163
}
164
165
-
var sourceRepo *db.Repo
166
if source != "" {
167
sourceRepo, err = db.GetRepoByAtUri(f.rr.execer, source)
168
if err != nil {
···
191
Knot: knot,
192
Spindle: f.Spindle,
193
Roles: f.RolesInRepo(user),
194
-
Stats: db.RepoStats{
195
StarCount: starCount,
196
IssueCount: issueCount,
197
PullCount: pullCount,
···
16
"github.com/go-chi/chi/v5"
17
"tangled.org/core/appview/config"
18
"tangled.org/core/appview/db"
19
+
"tangled.org/core/appview/models"
20
"tangled.org/core/appview/oauth"
21
"tangled.org/core/appview/pages"
22
"tangled.org/core/appview/pages/repoinfo"
···
25
)
26
27
type ResolvedRepo struct {
28
+
models.Repo
29
OwnerId identity.Identity
30
CurrentDir string
31
Ref string
···
45
}
46
47
func (rr *RepoResolver) Resolve(r *http.Request) (*ResolvedRepo, error) {
48
+
repo, ok := r.Context().Value("repo").(*models.Repo)
49
if !ok {
50
log.Println("malformed middleware: `repo` not exist in context")
51
return nil, fmt.Errorf("malformed middleware")
···
163
log.Println("failed to get repo source for ", repoAt, err)
164
}
165
166
+
var sourceRepo *models.Repo
167
if source != "" {
168
sourceRepo, err = db.GetRepoByAtUri(f.rr.execer, source)
169
if err != nil {
···
192
Knot: knot,
193
Spindle: f.Spindle,
194
Roles: f.RolesInRepo(user),
195
+
Stats: models.RepoStats{
196
StarCount: starCount,
197
IssueCount: issueCount,
198
PullCount: pullCount,
+2
-1
appview/spindles/spindles.go
+2
-1
appview/spindles/spindles.go
···
13
"tangled.org/core/appview/config"
14
"tangled.org/core/appview/db"
15
"tangled.org/core/appview/middleware"
16
"tangled.org/core/appview/oauth"
17
"tangled.org/core/appview/pages"
18
"tangled.org/core/appview/serververify"
···
115
}
116
117
// organize repos by did
118
-
repoMap := make(map[string][]db.Repo)
119
for _, r := range repos {
120
repoMap[r.Did] = append(repoMap[r.Did], r)
121
}
···
13
"tangled.org/core/appview/config"
14
"tangled.org/core/appview/db"
15
"tangled.org/core/appview/middleware"
16
+
"tangled.org/core/appview/models"
17
"tangled.org/core/appview/oauth"
18
"tangled.org/core/appview/pages"
19
"tangled.org/core/appview/serververify"
···
116
}
117
118
// organize repos by did
119
+
repoMap := make(map[string][]models.Repo)
120
for _, r := range repos {
121
repoMap[r.Did] = append(repoMap[r.Did], r)
122
}
+4
-4
appview/state/git_http.go
+4
-4
appview/state/git_http.go
···
8
9
"github.com/bluesky-social/indigo/atproto/identity"
10
"github.com/go-chi/chi/v5"
11
-
"tangled.org/core/appview/db"
12
)
13
14
func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) {
15
user := r.Context().Value("resolvedId").(identity.Identity)
16
-
repo := r.Context().Value("repo").(*db.Repo)
17
18
scheme := "https"
19
if s.config.Core.Dev {
···
31
http.Error(w, "failed to resolve user", http.StatusInternalServerError)
32
return
33
}
34
-
repo := r.Context().Value("repo").(*db.Repo)
35
36
scheme := "https"
37
if s.config.Core.Dev {
···
48
http.Error(w, "failed to resolve user", http.StatusInternalServerError)
49
return
50
}
51
-
repo := r.Context().Value("repo").(*db.Repo)
52
53
scheme := "https"
54
if s.config.Core.Dev {
···
8
9
"github.com/bluesky-social/indigo/atproto/identity"
10
"github.com/go-chi/chi/v5"
11
+
"tangled.org/core/appview/models"
12
)
13
14
func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) {
15
user := r.Context().Value("resolvedId").(identity.Identity)
16
+
repo := r.Context().Value("repo").(*models.Repo)
17
18
scheme := "https"
19
if s.config.Core.Dev {
···
31
http.Error(w, "failed to resolve user", http.StatusInternalServerError)
32
return
33
}
34
+
repo := r.Context().Value("repo").(*models.Repo)
35
36
scheme := "https"
37
if s.config.Core.Dev {
···
48
http.Error(w, "failed to resolve user", http.StatusInternalServerError)
49
return
50
}
51
+
repo := r.Context().Value("repo").(*models.Repo)
52
53
scheme := "https"
54
if s.config.Core.Dev {
+2
-2
appview/state/profile.go
+2
-2
appview/state/profile.go
···
131
}
132
133
// filter out ones that are pinned
134
-
pinnedRepos := []db.Repo{}
135
for i, r := range repos {
136
// if this is a pinned repo, add it
137
if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) {
···
149
l.Error("failed to fetch collaborating repos", "err", err)
150
}
151
152
-
pinnedCollaboratingRepos := []db.Repo{}
153
for _, r := range collaboratingRepos {
154
// if this is a pinned repo, add it
155
if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) {
···
131
}
132
133
// filter out ones that are pinned
134
+
pinnedRepos := []models.Repo{}
135
for i, r := range repos {
136
// if this is a pinned repo, add it
137
if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) {
···
149
l.Error("failed to fetch collaborating repos", "err", err)
150
}
151
152
+
pinnedCollaboratingRepos := []models.Repo{}
153
for _, r := range collaboratingRepos {
154
// if this is a pinned repo, add it
155
if slices.Contains(profile.Profile.PinnedRepos[:], r.RepoAt()) {
+3
-2
appview/state/star.go
+3
-2
appview/state/star.go
···
10
lexutil "github.com/bluesky-social/indigo/lex/util"
11
"tangled.org/core/api/tangled"
12
"tangled.org/core/appview/db"
13
"tangled.org/core/appview/pages"
14
"tangled.org/core/tid"
15
)
···
77
s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{
78
IsStarred: true,
79
RepoAt: subjectUri,
80
-
Stats: db.RepoStats{
81
StarCount: starCount,
82
},
83
})
···
119
s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{
120
IsStarred: false,
121
RepoAt: subjectUri,
122
-
Stats: db.RepoStats{
123
StarCount: starCount,
124
},
125
})
···
10
lexutil "github.com/bluesky-social/indigo/lex/util"
11
"tangled.org/core/api/tangled"
12
"tangled.org/core/appview/db"
13
+
"tangled.org/core/appview/models"
14
"tangled.org/core/appview/pages"
15
"tangled.org/core/tid"
16
)
···
78
s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{
79
IsStarred: true,
80
RepoAt: subjectUri,
81
+
Stats: models.RepoStats{
82
StarCount: starCount,
83
},
84
})
···
120
s.pages.RepoStarFragment(w, pages.RepoStarFragmentParams{
121
IsStarred: false,
122
RepoAt: subjectUri,
123
+
Stats: models.RepoStats{
124
StarCount: starCount,
125
},
126
})
+2
-2
appview/state/state.go
+2
-2
appview/state/state.go
···
23
"tangled.org/core/appview/cache/session"
24
"tangled.org/core/appview/config"
25
"tangled.org/core/appview/db"
26
"tangled.org/core/appview/notify"
27
"tangled.org/core/appview/oauth"
28
"tangled.org/core/appview/pages"
···
36
tlog "tangled.org/core/log"
37
"tangled.org/core/rbac"
38
"tangled.org/core/tid"
39
-
// xrpcerr "tangled.org/core/xrpc/errors"
40
)
41
42
type State struct {
···
433
434
// create atproto record for this repo
435
rkey := tid.TID()
436
-
repo := &db.Repo{
437
Did: user.Did,
438
Name: repoName,
439
Knot: domain,
···
23
"tangled.org/core/appview/cache/session"
24
"tangled.org/core/appview/config"
25
"tangled.org/core/appview/db"
26
+
"tangled.org/core/appview/models"
27
"tangled.org/core/appview/notify"
28
"tangled.org/core/appview/oauth"
29
"tangled.org/core/appview/pages"
···
37
tlog "tangled.org/core/log"
38
"tangled.org/core/rbac"
39
"tangled.org/core/tid"
40
)
41
42
type State struct {
···
433
434
// create atproto record for this repo
435
rkey := tid.TID()
436
+
repo := &models.Repo{
437
Did: user.Did,
438
Name: repoName,
439
Knot: domain,