Monorepo for Tangled tangled.org
856
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: adds issues into timeline #302

open opened by willdot.net targeting master from willdot.net/tangled-fork: include-issues-timeline

This will add issues being created into the timeline.

I think this is a nice step towards making the timeline be a bit more "custom" because when we get the ability to filter the timeline to be a bit more personalised, this could allow users to see issues being raised in repos they follow / start etc.

If you're happy with this, I can do pull requests next :)

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:dadhhalkfcq3gucaq25hjqon/sh.tangled.repo.pull/3mkuzc3lcfd22
+116
Diff #3
+57
appview/db/timeline.go
··· 1 1 package db 2 2 3 3 import ( 4 + "fmt" 5 + "slices" 4 6 "sort" 5 7 6 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 + "tangled.org/core/api/tangled" 7 10 "tangled.org/core/appview/models" 8 11 "tangled.org/core/appview/pagination" 9 12 "tangled.org/core/orm" ··· 47 50 return nil, err 48 51 } 49 52 53 + issues, err := getTimelineIssues(e, limit, loggedInUserDid, userIsFollowing) 54 + if err != nil { 55 + return nil, err 56 + } 57 + 50 58 events = append(events, repos...) 51 59 events = append(events, stars...) 52 60 events = append(events, follows...) 61 + events = append(events, issues...) 53 62 54 63 sort.Slice(events, func(i, j int) bool { 55 64 return events[i].EventAt.After(events[j].EventAt) ··· 278 287 279 288 return events, nil 280 289 } 290 + 291 + func getTimelineIssues(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { 292 + filters := make([]orm.Filter, 0) 293 + if userIsFollowing != nil { 294 + filters = append(filters, orm.FilterIn("owner_did", userIsFollowing)) 295 + } 296 + filters = append(filters, orm.FilterEq("open", 1)) 297 + 298 + issues, err := GetIssuesPaginated(e, pagination.Page{Limit: limit}, filters...) 299 + if err != nil { 300 + return nil, err 301 + } 302 + 303 + var labels []string 304 + 305 + for _, issue := range issues { 306 + for uri := range issue.Labels.Inner() { 307 + if !slices.Contains(labels, uri) { 308 + labels = append(labels, uri) 309 + } 310 + } 311 + } 312 + 313 + labelDefs, err := GetLabelDefinitions( 314 + e, 315 + orm.FilterIn("at_uri", labels), 316 + orm.FilterContains("scope", tangled.RepoIssueNSID), 317 + ) 318 + if err != nil { 319 + return nil, fmt.Errorf("fetching labels for issues: %w", err) 320 + } 321 + 322 + defs := make(map[string]*models.LabelDefinition) 323 + for _, l := range labelDefs { 324 + defs[l.AtUri().String()] = &l 325 + } 326 + 327 + var events []models.TimelineEvent 328 + for _, issue := range issues { 329 + events = append(events, models.TimelineEvent{ 330 + Issue: &issue, 331 + EventAt: issue.Created, 332 + LabelDefs: defs, 333 + }) 334 + } 335 + 336 + return events, nil 337 + }
+4
appview/models/timeline.go
··· 6 6 *Repo 7 7 *Follow 8 8 *RepoStar 9 + *Issue 9 10 10 11 EventAt time.Time 11 12 ··· 20 21 // optional: populate only if event is Repo 21 22 IsStarred bool 22 23 StarCount int64 24 + 25 + // optional: populate only if event if Issue 26 + LabelDefs map[string]*LabelDefinition 23 27 } 24 28 25 29 // TimelineGroup is a primary TimelineEvent plus zero or more peer events
+55
appview/pages/templates/timeline/fragments/timeline.html
··· 19 19 {{ template "timeline/fragments/starEvent" (list $ $g) }} 20 20 {{ else if $primary.Follow }} 21 21 {{ template "timeline/fragments/followEvent" (list $ $g) }} 22 + {{ else if $primary.Issue }} 23 + {{ template "timeline/fragments/issueEvent" (list $ $g) }} 22 24 {{ end }} 23 25 </div> 24 26 </div> ··· 85 87 {{ end }} 86 88 {{ end }} 87 89 90 + {{ define "timeline/fragments/issueEvent" }} 91 + {{ $root := index . 0 }} 92 + {{ $group := index . 1 }} 93 + {{ $event := $group.Primary }} 94 + {{ $issue := $event.Issue }} 95 + {{ with $issue }} 96 + {{ $repo := .Repo}} 97 + {{ $userHandle := resolve .Did }} 98 + {{ $repoOwnerHandle := resolve $repo.Did }} 99 + <div class="pl-6 py-2 bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-300 flex flex-wrap items-center gap-2 text-sm"> 100 + {{ template "user/fragments/picHandleLink" .Did }} 101 + created an issue in 102 + <a href="/{{ $repoOwnerHandle }}/{{ $repo.Name }}" class="no-underline hover:underline"> 103 + {{ $repoOwnerHandle | truncateAt30 }}/{{ $repo.Name }} 104 + </a> 105 + <span class="text-gray-700 dark:text-gray-400 text-xs">{{ template "repo/fragments/time" .Created }}</span> 106 + </div> 107 + <div class="rounded drop-shadow-sm bg-white px-6 py-4 dark:bg-gray-800 dark:border-gray-700"> 108 + <div class="pb-2"> 109 + <a href="/{{ $repoOwnerHandle }}/{{ $repo.Name }}/issues/{{ .IssueId }}" class="no-underline hover:underline"> 110 + {{ .Title }} 111 + <span class="text-gray-500 dark:text-gray-400">#{{ .IssueId }}</span> 112 + </a> 113 + </div> 114 + <div class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1"> 115 + {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 116 + {{ $icon := "ban" }} 117 + {{ $state := "closed" }} 118 + {{ if .Open }} 119 + {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 120 + {{ $icon = "circle-dot" }} 121 + {{ $state = "open" }} 122 + {{ end }} 123 + 124 + <span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }}"> 125 + {{ i $icon "w-3 h-3 mr-1.5 text-white dark:text-white" }} 126 + <span class="text-white dark:text-white text-sm">{{ $state }}</span> 127 + </span> 128 + 129 + <span class="before:content-['·']"> 130 + {{ template "repo/fragments/time" .Created }} 131 + </span> 132 + {{ $state := .Labels }} 133 + {{ range $k, $d := $event.LabelDefs }} 134 + {{ range $v, $s := $state.GetValSet $d.AtUri.String }} 135 + {{ template "labels/fragments/label" (dict "def" $d "val" $v "withPrefix" true) }} 136 + {{ end }} 137 + {{ end }} 138 + </div> 139 + </div> 140 + {{ end }} 141 + {{ end }} 142 + 88 143 {{ define "timeline/fragments/followEvent" }} 89 144 {{ $root := index . 0 }} 90 145 {{ $group := index . 1 }}

History

4 rounds 0 comments
sign up or login to add to the discussion
1 commit
expand
appview: adds issues into timeline
merge conflicts detected
expand
  • appview/db/timeline.go:1
expand 0 comments
1 commit
expand
appview: adds issues into timeline
expand 0 comments
1 commit
expand
appview: adds issues into timeline
expand 0 comments
1 commit
expand
appview: adds issues into timeline
expand 0 comments