+15
-200
appview/db/issues.go
+15
-200
appview/db/issues.go
···
10
10
"time"
11
11
12
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
-
"tangled.org/core/api/tangled"
14
13
"tangled.org/core/appview/models"
15
14
"tangled.org/core/appview/pagination"
16
15
)
17
16
18
-
type Issue struct {
19
-
Id int64
20
-
Did string
21
-
Rkey string
22
-
RepoAt syntax.ATURI
23
-
IssueId int
24
-
Created time.Time
25
-
Edited *time.Time
26
-
Deleted *time.Time
27
-
Title string
28
-
Body string
29
-
Open bool
30
-
31
-
// optionally, populate this when querying for reverse mappings
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 {
39
-
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.Did, tangled.RepoIssueNSID, i.Rkey))
40
-
}
41
-
42
-
func (i *Issue) AsRecord() tangled.RepoIssue {
43
-
return tangled.RepoIssue{
44
-
Repo: i.RepoAt.String(),
45
-
Title: i.Title,
46
-
Body: &i.Body,
47
-
CreatedAt: i.Created.Format(time.RFC3339),
48
-
}
49
-
}
50
-
51
-
func (i *Issue) State() string {
52
-
if i.Open {
53
-
return "open"
54
-
}
55
-
return "closed"
56
-
}
57
-
58
-
type CommentListItem struct {
59
-
Self *IssueComment
60
-
Replies []*IssueComment
61
-
}
62
-
63
-
func (i *Issue) CommentList() []CommentListItem {
64
-
// Create a map to quickly find comments by their aturi
65
-
toplevel := make(map[string]*CommentListItem)
66
-
var replies []*IssueComment
67
-
68
-
// collect top level comments into the map
69
-
for _, comment := range i.Comments {
70
-
if comment.IsTopLevel() {
71
-
toplevel[comment.AtUri().String()] = &CommentListItem{
72
-
Self: &comment,
73
-
}
74
-
} else {
75
-
replies = append(replies, &comment)
76
-
}
77
-
}
78
-
79
-
for _, r := range replies {
80
-
parentAt := *r.ReplyTo
81
-
if parent, exists := toplevel[parentAt]; exists {
82
-
parent.Replies = append(parent.Replies, r)
83
-
}
84
-
}
85
-
86
-
var listing []CommentListItem
87
-
for _, v := range toplevel {
88
-
listing = append(listing, *v)
89
-
}
90
-
91
-
// sort everything
92
-
sortFunc := func(a, b *IssueComment) bool {
93
-
return a.Created.Before(b.Created)
94
-
}
95
-
sort.Slice(listing, func(i, j int) bool {
96
-
return sortFunc(listing[i].Self, listing[j].Self)
97
-
})
98
-
for _, r := range listing {
99
-
sort.Slice(r.Replies, func(i, j int) bool {
100
-
return sortFunc(r.Replies[i], r.Replies[j])
101
-
})
102
-
}
103
-
104
-
return listing
105
-
}
106
-
107
-
func (i *Issue) Participants() []string {
108
-
participantSet := make(map[string]struct{})
109
-
participants := []string{}
110
-
111
-
addParticipant := func(did string) {
112
-
if _, exists := participantSet[did]; !exists {
113
-
participantSet[did] = struct{}{}
114
-
participants = append(participants, did)
115
-
}
116
-
}
117
-
118
-
addParticipant(i.Did)
119
-
120
-
for _, c := range i.Comments {
121
-
addParticipant(c.Did)
122
-
}
123
-
124
-
return participants
125
-
}
126
-
127
-
func IssueFromRecord(did, rkey string, record tangled.RepoIssue) Issue {
128
-
created, err := time.Parse(time.RFC3339, record.CreatedAt)
129
-
if err != nil {
130
-
created = time.Now()
131
-
}
132
-
133
-
body := ""
134
-
if record.Body != nil {
135
-
body = *record.Body
136
-
}
137
-
138
-
return Issue{
139
-
RepoAt: syntax.ATURI(record.Repo),
140
-
Did: did,
141
-
Rkey: rkey,
142
-
Created: created,
143
-
Title: record.Title,
144
-
Body: body,
145
-
Open: true, // new issues are open by default
146
-
}
147
-
}
148
-
149
-
type IssueComment struct {
150
-
Id int64
151
-
Did string
152
-
Rkey string
153
-
IssueAt string
154
-
ReplyTo *string
155
-
Body string
156
-
Created time.Time
157
-
Edited *time.Time
158
-
Deleted *time.Time
159
-
}
160
-
161
-
func (i *IssueComment) AtUri() syntax.ATURI {
162
-
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.Did, tangled.RepoIssueCommentNSID, i.Rkey))
163
-
}
164
-
165
-
func (i *IssueComment) AsRecord() tangled.RepoIssueComment {
166
-
return tangled.RepoIssueComment{
167
-
Body: i.Body,
168
-
Issue: i.IssueAt,
169
-
CreatedAt: i.Created.Format(time.RFC3339),
170
-
ReplyTo: i.ReplyTo,
171
-
}
172
-
}
173
-
174
-
func (i *IssueComment) IsTopLevel() bool {
175
-
return i.ReplyTo == nil
176
-
}
177
-
178
-
func IssueCommentFromRecord(did, rkey string, record tangled.RepoIssueComment) (*IssueComment, error) {
179
-
created, err := time.Parse(time.RFC3339, record.CreatedAt)
180
-
if err != nil {
181
-
created = time.Now()
182
-
}
183
-
184
-
ownerDid := did
185
-
186
-
if _, err = syntax.ParseATURI(record.Issue); err != nil {
187
-
return nil, err
188
-
}
189
-
190
-
comment := IssueComment{
191
-
Did: ownerDid,
192
-
Rkey: rkey,
193
-
Body: record.Body,
194
-
IssueAt: record.Issue,
195
-
ReplyTo: record.ReplyTo,
196
-
Created: created,
197
-
}
198
-
199
-
return &comment, nil
200
-
}
201
-
202
-
func PutIssue(tx *sql.Tx, issue *Issue) error {
17
+
func PutIssue(tx *sql.Tx, issue *models.Issue) error {
203
18
// ensure sequence exists
204
19
_, err := tx.Exec(`
205
20
insert or ignore into repo_issue_seqs (repo_at, next_issue_id)
···
234
49
}
235
50
}
236
51
237
-
func createNewIssue(tx *sql.Tx, issue *Issue) error {
52
+
func createNewIssue(tx *sql.Tx, issue *models.Issue) error {
238
53
// get next issue_id
239
54
var newIssueId int
240
55
err := tx.QueryRow(`
···
257
72
return row.Scan(&issue.Id, &issue.IssueId)
258
73
}
259
74
260
-
func updateIssue(tx *sql.Tx, issue *Issue) error {
75
+
func updateIssue(tx *sql.Tx, issue *models.Issue) error {
261
76
// update existing issue
262
77
_, err := tx.Exec(`
263
78
update issues
···
267
82
return err
268
83
}
269
84
270
-
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...filter) ([]Issue, error) {
271
-
issueMap := make(map[string]*Issue) // at-uri -> issue
85
+
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...filter) ([]models.Issue, error) {
86
+
issueMap := make(map[string]*models.Issue) // at-uri -> issue
272
87
273
88
var conditions []string
274
89
var args []any
···
323
138
defer rows.Close()
324
139
325
140
for rows.Next() {
326
-
var issue Issue
141
+
var issue models.Issue
327
142
var createdAt string
328
143
var editedAt, deletedAt sql.Null[string]
329
144
var rowNum int64
···
416
231
}
417
232
}
418
233
419
-
var issues []Issue
234
+
var issues []models.Issue
420
235
for _, i := range issueMap {
421
236
issues = append(issues, *i)
422
237
}
···
428
243
return issues, nil
429
244
}
430
245
431
-
func GetIssues(e Execer, filters ...filter) ([]Issue, error) {
246
+
func GetIssues(e Execer, filters ...filter) ([]models.Issue, error) {
432
247
return GetIssuesPaginated(e, pagination.FirstPage(), filters...)
433
248
}
434
249
435
-
func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) {
250
+
func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*models.Issue, error) {
436
251
query := `select id, owner_did, rkey, created, title, body, open from issues where repo_at = ? and issue_id = ?`
437
252
row := e.QueryRow(query, repoAt, issueId)
438
253
439
-
var issue Issue
254
+
var issue models.Issue
440
255
var createdAt string
441
256
err := row.Scan(&issue.Id, &issue.Did, &issue.Rkey, &createdAt, &issue.Title, &issue.Body, &issue.Open)
442
257
if err != nil {
···
452
267
return &issue, nil
453
268
}
454
269
455
-
func AddIssueComment(e Execer, c IssueComment) (int64, error) {
270
+
func AddIssueComment(e Execer, c models.IssueComment) (int64, error) {
456
271
result, err := e.Exec(
457
272
`insert into issue_comments (
458
273
did,
···
514
329
return err
515
330
}
516
331
517
-
func GetIssueComments(e Execer, filters ...filter) ([]IssueComment, error) {
518
-
var comments []IssueComment
332
+
func GetIssueComments(e Execer, filters ...filter) ([]models.IssueComment, error) {
333
+
var comments []models.IssueComment
519
334
520
335
var conditions []string
521
336
var args []any
···
551
366
}
552
367
553
368
for rows.Next() {
554
-
var comment IssueComment
369
+
var comment models.IssueComment
555
370
var created string
556
371
var rkey, edited, deleted, replyTo sql.Null[string]
557
372
err := rows.Scan(
···
670
485
671
486
var count models.IssueCount
672
487
if err := row.Scan(&count.Open, &count.Closed); err != nil {
673
-
return models.IssueCount{0, 0}, err
488
+
return models.IssueCount{}, err
674
489
}
675
490
676
491
return count, nil
+1
-1
appview/db/profile.go
+1
-1
appview/db/profile.go
+2
-2
appview/ingester.go
+2
-2
appview/ingester.go
···
803
803
return err
804
804
}
805
805
806
-
issue := db.IssueFromRecord(did, rkey, record)
806
+
issue := models.IssueFromRecord(did, rkey, record)
807
807
808
808
if err := i.Validator.ValidateIssue(&issue); err != nil {
809
809
return fmt.Errorf("failed to validate issue: %w", err)
···
869
869
return fmt.Errorf("invalid record: %w", err)
870
870
}
871
871
872
-
comment, err := db.IssueCommentFromRecord(did, rkey, record)
872
+
comment, err := models.IssueCommentFromRecord(did, rkey, record)
873
873
if err != nil {
874
874
return fmt.Errorf("failed to parse comment from record: %w", err)
875
875
}
+13
-13
appview/issues/issues.go
+13
-13
appview/issues/issues.go
···
76
76
return
77
77
}
78
78
79
-
issue, ok := r.Context().Value("issue").(*db.Issue)
79
+
issue, ok := r.Context().Value("issue").(*models.Issue)
80
80
if !ok {
81
81
l.Error("failed to get issue")
82
82
rp.pages.Error404(w)
···
130
130
return
131
131
}
132
132
133
-
issue, ok := r.Context().Value("issue").(*db.Issue)
133
+
issue, ok := r.Context().Value("issue").(*models.Issue)
134
134
if !ok {
135
135
l.Error("failed to get issue")
136
136
rp.pages.Error404(w)
···
226
226
return
227
227
}
228
228
229
-
issue, ok := r.Context().Value("issue").(*db.Issue)
229
+
issue, ok := r.Context().Value("issue").(*models.Issue)
230
230
if !ok {
231
231
l.Error("failed to get issue")
232
232
rp.pages.Notice(w, noticeId, "Failed to delete issue.")
···
273
273
return
274
274
}
275
275
276
-
issue, ok := r.Context().Value("issue").(*db.Issue)
276
+
issue, ok := r.Context().Value("issue").(*models.Issue)
277
277
if !ok {
278
278
l.Error("failed to get issue")
279
279
rp.pages.Error404(w)
···
319
319
return
320
320
}
321
321
322
-
issue, ok := r.Context().Value("issue").(*db.Issue)
322
+
issue, ok := r.Context().Value("issue").(*models.Issue)
323
323
if !ok {
324
324
l.Error("failed to get issue")
325
325
rp.pages.Error404(w)
···
363
363
return
364
364
}
365
365
366
-
issue, ok := r.Context().Value("issue").(*db.Issue)
366
+
issue, ok := r.Context().Value("issue").(*models.Issue)
367
367
if !ok {
368
368
l.Error("failed to get issue")
369
369
rp.pages.Error404(w)
···
382
382
replyTo = &replyToUri
383
383
}
384
384
385
-
comment := db.IssueComment{
385
+
comment := models.IssueComment{
386
386
Did: user.Did,
387
387
Rkey: tid.TID(),
388
388
IssueAt: issue.AtUri().String(),
···
446
446
return
447
447
}
448
448
449
-
issue, ok := r.Context().Value("issue").(*db.Issue)
449
+
issue, ok := r.Context().Value("issue").(*models.Issue)
450
450
if !ok {
451
451
l.Error("failed to get issue")
452
452
rp.pages.Error404(w)
···
487
487
return
488
488
}
489
489
490
-
issue, ok := r.Context().Value("issue").(*db.Issue)
490
+
issue, ok := r.Context().Value("issue").(*models.Issue)
491
491
if !ok {
492
492
l.Error("failed to get issue")
493
493
rp.pages.Error404(w)
···
591
591
return
592
592
}
593
593
594
-
issue, ok := r.Context().Value("issue").(*db.Issue)
594
+
issue, ok := r.Context().Value("issue").(*models.Issue)
595
595
if !ok {
596
596
l.Error("failed to get issue")
597
597
rp.pages.Error404(w)
···
632
632
return
633
633
}
634
634
635
-
issue, ok := r.Context().Value("issue").(*db.Issue)
635
+
issue, ok := r.Context().Value("issue").(*models.Issue)
636
636
if !ok {
637
637
l.Error("failed to get issue")
638
638
rp.pages.Error404(w)
···
673
673
return
674
674
}
675
675
676
-
issue, ok := r.Context().Value("issue").(*db.Issue)
676
+
issue, ok := r.Context().Value("issue").(*models.Issue)
677
677
if !ok {
678
678
l.Error("failed to get issue")
679
679
rp.pages.Error404(w)
···
829
829
RepoInfo: f.RepoInfo(user),
830
830
})
831
831
case http.MethodPost:
832
-
issue := &db.Issue{
832
+
issue := &models.Issue{
833
833
RepoAt: f.RepoAt(),
834
834
Rkey: tid.TID(),
835
835
Title: r.FormValue("title"),
+194
appview/models/issue.go
+194
appview/models/issue.go
···
1
+
package models
2
+
3
+
import (
4
+
"fmt"
5
+
"sort"
6
+
"time"
7
+
8
+
"github.com/bluesky-social/indigo/atproto/syntax"
9
+
"tangled.org/core/api/tangled"
10
+
)
11
+
12
+
type Issue struct {
13
+
Id int64
14
+
Did string
15
+
Rkey string
16
+
RepoAt syntax.ATURI
17
+
IssueId int
18
+
Created time.Time
19
+
Edited *time.Time
20
+
Deleted *time.Time
21
+
Title string
22
+
Body string
23
+
Open bool
24
+
25
+
// optionally, populate this when querying for reverse mappings
26
+
// like comment counts, parent repo etc.
27
+
Comments []IssueComment
28
+
Labels LabelState
29
+
Repo *Repo
30
+
}
31
+
32
+
func (i *Issue) AtUri() syntax.ATURI {
33
+
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.Did, tangled.RepoIssueNSID, i.Rkey))
34
+
}
35
+
36
+
func (i *Issue) AsRecord() tangled.RepoIssue {
37
+
return tangled.RepoIssue{
38
+
Repo: i.RepoAt.String(),
39
+
Title: i.Title,
40
+
Body: &i.Body,
41
+
CreatedAt: i.Created.Format(time.RFC3339),
42
+
}
43
+
}
44
+
45
+
func (i *Issue) State() string {
46
+
if i.Open {
47
+
return "open"
48
+
}
49
+
return "closed"
50
+
}
51
+
52
+
type CommentListItem struct {
53
+
Self *IssueComment
54
+
Replies []*IssueComment
55
+
}
56
+
57
+
func (i *Issue) CommentList() []CommentListItem {
58
+
// Create a map to quickly find comments by their aturi
59
+
toplevel := make(map[string]*CommentListItem)
60
+
var replies []*IssueComment
61
+
62
+
// collect top level comments into the map
63
+
for _, comment := range i.Comments {
64
+
if comment.IsTopLevel() {
65
+
toplevel[comment.AtUri().String()] = &CommentListItem{
66
+
Self: &comment,
67
+
}
68
+
} else {
69
+
replies = append(replies, &comment)
70
+
}
71
+
}
72
+
73
+
for _, r := range replies {
74
+
parentAt := *r.ReplyTo
75
+
if parent, exists := toplevel[parentAt]; exists {
76
+
parent.Replies = append(parent.Replies, r)
77
+
}
78
+
}
79
+
80
+
var listing []CommentListItem
81
+
for _, v := range toplevel {
82
+
listing = append(listing, *v)
83
+
}
84
+
85
+
// sort everything
86
+
sortFunc := func(a, b *IssueComment) bool {
87
+
return a.Created.Before(b.Created)
88
+
}
89
+
sort.Slice(listing, func(i, j int) bool {
90
+
return sortFunc(listing[i].Self, listing[j].Self)
91
+
})
92
+
for _, r := range listing {
93
+
sort.Slice(r.Replies, func(i, j int) bool {
94
+
return sortFunc(r.Replies[i], r.Replies[j])
95
+
})
96
+
}
97
+
98
+
return listing
99
+
}
100
+
101
+
func (i *Issue) Participants() []string {
102
+
participantSet := make(map[string]struct{})
103
+
participants := []string{}
104
+
105
+
addParticipant := func(did string) {
106
+
if _, exists := participantSet[did]; !exists {
107
+
participantSet[did] = struct{}{}
108
+
participants = append(participants, did)
109
+
}
110
+
}
111
+
112
+
addParticipant(i.Did)
113
+
114
+
for _, c := range i.Comments {
115
+
addParticipant(c.Did)
116
+
}
117
+
118
+
return participants
119
+
}
120
+
121
+
func IssueFromRecord(did, rkey string, record tangled.RepoIssue) Issue {
122
+
created, err := time.Parse(time.RFC3339, record.CreatedAt)
123
+
if err != nil {
124
+
created = time.Now()
125
+
}
126
+
127
+
body := ""
128
+
if record.Body != nil {
129
+
body = *record.Body
130
+
}
131
+
132
+
return Issue{
133
+
RepoAt: syntax.ATURI(record.Repo),
134
+
Did: did,
135
+
Rkey: rkey,
136
+
Created: created,
137
+
Title: record.Title,
138
+
Body: body,
139
+
Open: true, // new issues are open by default
140
+
}
141
+
}
142
+
143
+
type IssueComment struct {
144
+
Id int64
145
+
Did string
146
+
Rkey string
147
+
IssueAt string
148
+
ReplyTo *string
149
+
Body string
150
+
Created time.Time
151
+
Edited *time.Time
152
+
Deleted *time.Time
153
+
}
154
+
155
+
func (i *IssueComment) AtUri() syntax.ATURI {
156
+
return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.Did, tangled.RepoIssueCommentNSID, i.Rkey))
157
+
}
158
+
159
+
func (i *IssueComment) AsRecord() tangled.RepoIssueComment {
160
+
return tangled.RepoIssueComment{
161
+
Body: i.Body,
162
+
Issue: i.IssueAt,
163
+
CreatedAt: i.Created.Format(time.RFC3339),
164
+
ReplyTo: i.ReplyTo,
165
+
}
166
+
}
167
+
168
+
func (i *IssueComment) IsTopLevel() bool {
169
+
return i.ReplyTo == nil
170
+
}
171
+
172
+
func IssueCommentFromRecord(did, rkey string, record tangled.RepoIssueComment) (*IssueComment, error) {
173
+
created, err := time.Parse(time.RFC3339, record.CreatedAt)
174
+
if err != nil {
175
+
created = time.Now()
176
+
}
177
+
178
+
ownerDid := did
179
+
180
+
if _, err = syntax.ParseATURI(record.Issue); err != nil {
181
+
return nil, err
182
+
}
183
+
184
+
comment := IssueComment{
185
+
Did: ownerDid,
186
+
Rkey: rkey,
187
+
Body: record.Body,
188
+
IssueAt: record.Issue,
189
+
ReplyTo: record.ReplyTo,
190
+
Created: created,
191
+
}
192
+
193
+
return &comment, nil
194
+
}
+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
···
13
13
NewStar(ctx context.Context, star *db.Star)
14
14
DeleteStar(ctx context.Context, star *db.Star)
15
15
16
-
NewIssue(ctx context.Context, issue *db.Issue)
16
+
NewIssue(ctx context.Context, issue *models.Issue)
17
17
18
18
NewFollow(ctx context.Context, follow *models.Follow)
19
19
DeleteFollow(ctx context.Context, follow *models.Follow)
···
38
38
func (m *BaseNotifier) NewStar(ctx context.Context, star *db.Star) {}
39
39
func (m *BaseNotifier) DeleteStar(ctx context.Context, star *db.Star) {}
40
40
41
-
func (m *BaseNotifier) NewIssue(ctx context.Context, issue *db.Issue) {}
41
+
func (m *BaseNotifier) NewIssue(ctx context.Context, issue *models.Issue) {}
42
42
43
43
func (m *BaseNotifier) NewFollow(ctx context.Context, follow *models.Follow) {}
44
44
func (m *BaseNotifier) DeleteFollow(ctx context.Context, follow *models.Follow) {}
+13
-13
appview/pages/pages.go
+13
-13
appview/pages/pages.go
···
889
889
LoggedInUser *oauth.User
890
890
RepoInfo repoinfo.RepoInfo
891
891
Active string
892
-
Issues []db.Issue
892
+
Issues []models.Issue
893
893
LabelDefs map[string]*models.LabelDefinition
894
894
Page pagination.Page
895
895
FilteringByOpen bool
···
904
904
LoggedInUser *oauth.User
905
905
RepoInfo repoinfo.RepoInfo
906
906
Active string
907
-
Issue *db.Issue
908
-
CommentList []db.CommentListItem
907
+
Issue *models.Issue
908
+
CommentList []models.CommentListItem
909
909
LabelDefs map[string]*models.LabelDefinition
910
910
911
911
OrderedReactionKinds []db.ReactionKind
···
921
921
type EditIssueParams struct {
922
922
LoggedInUser *oauth.User
923
923
RepoInfo repoinfo.RepoInfo
924
-
Issue *db.Issue
924
+
Issue *models.Issue
925
925
Action string
926
926
}
927
927
···
944
944
type RepoNewIssueParams struct {
945
945
LoggedInUser *oauth.User
946
946
RepoInfo repoinfo.RepoInfo
947
-
Issue *db.Issue // existing issue if any -- passed when editing
947
+
Issue *models.Issue // existing issue if any -- passed when editing
948
948
Active string
949
949
Action string
950
950
}
···
958
958
type EditIssueCommentParams struct {
959
959
LoggedInUser *oauth.User
960
960
RepoInfo repoinfo.RepoInfo
961
-
Issue *db.Issue
962
-
Comment *db.IssueComment
961
+
Issue *models.Issue
962
+
Comment *models.IssueComment
963
963
}
964
964
965
965
func (p *Pages) EditIssueCommentFragment(w io.Writer, params EditIssueCommentParams) error {
···
969
969
type ReplyIssueCommentPlaceholderParams struct {
970
970
LoggedInUser *oauth.User
971
971
RepoInfo repoinfo.RepoInfo
972
-
Issue *db.Issue
973
-
Comment *db.IssueComment
972
+
Issue *models.Issue
973
+
Comment *models.IssueComment
974
974
}
975
975
976
976
func (p *Pages) ReplyIssueCommentPlaceholderFragment(w io.Writer, params ReplyIssueCommentPlaceholderParams) error {
···
980
980
type ReplyIssueCommentParams struct {
981
981
LoggedInUser *oauth.User
982
982
RepoInfo repoinfo.RepoInfo
983
-
Issue *db.Issue
984
-
Comment *db.IssueComment
983
+
Issue *models.Issue
984
+
Comment *models.IssueComment
985
985
}
986
986
987
987
func (p *Pages) ReplyIssueCommentFragment(w io.Writer, params ReplyIssueCommentParams) error {
···
991
991
type IssueCommentBodyParams struct {
992
992
LoggedInUser *oauth.User
993
993
RepoInfo repoinfo.RepoInfo
994
-
Issue *db.Issue
995
-
Comment *db.IssueComment
994
+
Issue *models.Issue
995
+
Comment *models.IssueComment
996
996
}
997
997
998
998
func (p *Pages) IssueCommentBodyFragment(w io.Writer, params IssueCommentBodyParams) error {
+1
-1
appview/posthog/notifier.go
+1
-1
appview/posthog/notifier.go
+2
-1
appview/repo/feed.go
+2
-1
appview/repo/feed.go
···
9
9
"time"
10
10
11
11
"tangled.org/core/appview/db"
12
+
"tangled.org/core/appview/models"
12
13
"tangled.org/core/appview/pagination"
13
14
"tangled.org/core/appview/reporesolver"
14
15
···
108
109
return items, nil
109
110
}
110
111
111
-
func (rp *Repo) createIssueItem(ctx context.Context, issue db.Issue, f *reporesolver.ResolvedRepo) (*feeds.Item, error) {
112
+
func (rp *Repo) createIssueItem(ctx context.Context, issue models.Issue, f *reporesolver.ResolvedRepo) (*feeds.Item, error) {
112
113
owner, err := rp.idResolver.ResolveIdent(ctx, issue.Did)
113
114
if err != nil {
114
115
return nil, err
+2
-2
appview/state/profile.go
+2
-2
appview/state/profile.go
···
467
467
return nil
468
468
}
469
469
470
-
func (s *State) addIssueItems(ctx context.Context, feed *feeds.Feed, issues []*db.Issue, author *feeds.Author) error {
470
+
func (s *State) addIssueItems(ctx context.Context, feed *feeds.Feed, issues []*models.Issue, author *feeds.Author) error {
471
471
for _, issue := range issues {
472
472
owner, err := s.idResolver.ResolveIdent(ctx, issue.Repo.Did)
473
473
if err != nil {
···
499
499
}
500
500
}
501
501
502
-
func (s *State) createIssueItem(issue *db.Issue, owner *identity.Identity, author *feeds.Author) *feeds.Item {
502
+
func (s *State) createIssueItem(issue *models.Issue, owner *identity.Identity, author *feeds.Author) *feeds.Item {
503
503
return &feeds.Item{
504
504
Title: fmt.Sprintf("%s created issue '%s' in @%s/%s", author.Name, issue.Title, owner.Handle, issue.Repo.Name),
505
505
Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s/issues/%d", s.config.Core.AppviewHost, owner.Handle, issue.Repo.Name, issue.IssueId), Type: "text/html", Rel: "alternate"},
+3
-2
appview/validator/issue.go
+3
-2
appview/validator/issue.go
···
5
5
"strings"
6
6
7
7
"tangled.org/core/appview/db"
8
+
"tangled.org/core/appview/models"
8
9
)
9
10
10
-
func (v *Validator) ValidateIssueComment(comment *db.IssueComment) error {
11
+
func (v *Validator) ValidateIssueComment(comment *models.IssueComment) error {
11
12
// if comments have parents, only ingest ones that are 1 level deep
12
13
if comment.ReplyTo != nil {
13
14
parents, err := db.GetIssueComments(v.db, db.FilterEq("at_uri", *comment.ReplyTo))
···
32
33
return nil
33
34
}
34
35
35
-
func (v *Validator) ValidateIssue(issue *db.Issue) error {
36
+
func (v *Validator) ValidateIssue(issue *models.Issue) error {
36
37
if issue.Title == "" {
37
38
return fmt.Errorf("issue title is empty")
38
39
}