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 -1
Diff #1
+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" ··· 42 45 return nil, err 43 46 } 44 47 48 + issues, err := getTimelineIssues(e, limit, loggedInUserDid, userIsFollowing) 49 + if err != nil { 50 + return nil, err 51 + } 52 + 45 53 events = append(events, repos...) 46 54 events = append(events, stars...) 47 55 events = append(events, follows...) 56 + events = append(events, issues...) 48 57 49 58 sort.Slice(events, func(i, j int) bool { 50 59 return events[i].EventAt.After(events[j].EventAt) ··· 240 249 241 250 return events, nil 242 251 } 252 + 253 + func getTimelineIssues(e Execer, limit int, loggedInUserDid string, userIsFollowing []string) ([]models.TimelineEvent, error) { 254 + filters := make([]orm.Filter, 0) 255 + if userIsFollowing != nil { 256 + filters = append(filters, orm.FilterIn("owner_did", userIsFollowing)) 257 + } 258 + filters = append(filters, orm.FilterEq("open", 1)) 259 + 260 + issues, err := GetIssuesPaginated(e, pagination.Page{Limit: limit}, filters...) 261 + if err != nil { 262 + return nil, err 263 + } 264 + 265 + var labels []string 266 + 267 + for _, issue := range issues { 268 + for uri := range issue.Labels.Inner() { 269 + if !slices.Contains(labels, uri) { 270 + labels = append(labels, uri) 271 + } 272 + } 273 + } 274 + 275 + labelDefs, err := GetLabelDefinitions( 276 + e, 277 + orm.FilterIn("at_uri", labels), 278 + orm.FilterContains("scope", tangled.RepoIssueNSID), 279 + ) 280 + if err != nil { 281 + return nil, fmt.Errorf("fetching labels for issues: %w", err) 282 + } 283 + 284 + defs := make(map[string]*models.LabelDefinition) 285 + for _, l := range labelDefs { 286 + defs[l.AtUri().String()] = &l 287 + } 288 + 289 + var events []models.TimelineEvent 290 + for _, issue := range issues { 291 + events = append(events, models.TimelineEvent{ 292 + Issue: &issue, 293 + EventAt: issue.Created, 294 + LabelDefs: defs, 295 + }) 296 + } 297 + 298 + return events, nil 299 + }
+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 }
+55 -1
appview/pages/templates/timeline/fragments/timeline.html
··· 19 19 {{ template "timeline/fragments/starEvent" (list $ .) }} 20 20 {{ else if .Follow }} 21 21 {{ template "timeline/fragments/followEvent" (list $ .) }} 22 + {{ else if .Issue }} 23 + {{ template "timeline/fragments/issueEvent" (list $ .) }} 22 24 {{ end }} 23 25 </div> 24 26 {{ end }} ··· 78 80 {{ end }} 79 81 {{ end }} 80 82 83 + {{ define "timeline/fragments/issueEvent" }} 84 + {{ $root := index . 0 }} 85 + {{ $event := index . 1 }} 86 + {{ $issue := $event.Issue }} 87 + {{ with $issue }} 88 + {{ $repo := .Repo}} 89 + {{ $userHandle := resolve .Did }} 90 + {{ $repoOwnerHandle := resolve $repo.Did }} 91 + <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"> 92 + {{ template "user/fragments/picHandleLink" .Did }} 93 + created an issue in 94 + <a href="/{{ $repoOwnerHandle }}/{{ $repo.Name }}" class="no-underline hover:underline"> 95 + {{ $repoOwnerHandle | truncateAt30 }}/{{ $repo.Name }} 96 + </a> 97 + <span class="text-gray-700 dark:text-gray-400 text-xs">{{ template "repo/fragments/time" .Created }}</span> 98 + </div> 99 + <div class="rounded drop-shadow-sm bg-white px-6 py-4 dark:bg-gray-800 dark:border-gray-700"> 100 + <div class="pb-2"> 101 + <a href="/{{ $repoOwnerHandle }}/{{ $repo.Name }}/issues/{{ .IssueId }}" class="no-underline hover:underline"> 102 + {{ .Title }} 103 + <span class="text-gray-500 dark:text-gray-400">#{{ .IssueId }}</span> 104 + </a> 105 + </div> 106 + <div class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1"> 107 + {{ $bgColor := "bg-gray-800 dark:bg-gray-700" }} 108 + {{ $icon := "ban" }} 109 + {{ $state := "closed" }} 110 + {{ if .Open }} 111 + {{ $bgColor = "bg-green-600 dark:bg-green-700" }} 112 + {{ $icon = "circle-dot" }} 113 + {{ $state = "open" }} 114 + {{ end }} 115 + 116 + <span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }}"> 117 + {{ i $icon "w-3 h-3 mr-1.5 text-white dark:text-white" }} 118 + <span class="text-white dark:text-white text-sm">{{ $state }}</span> 119 + </span> 120 + 121 + <span class="before:content-['·']"> 122 + {{ template "repo/fragments/time" .Created }} 123 + </span> 124 + {{ $state := .Labels }} 125 + {{ range $k, $d := $event.LabelDefs }} 126 + {{ range $v, $s := $state.GetValSet $d.AtUri.String }} 127 + {{ template "labels/fragments/label" (dict "def" $d "val" $v "withPrefix" true) }} 128 + {{ end }} 129 + {{ end }} 130 + </div> 131 + </div> 132 + {{ end }} 133 + {{ end }} 134 + 81 135 {{ define "timeline/fragments/followEvent" }} 82 136 {{ $root := index . 0 }} 83 137 {{ $event := index . 1 }} ··· 94 148 {{ template "user/fragments/picHandleLink" $subjectHandle }} 95 149 <span class="text-gray-700 dark:text-gray-400 text-xs">{{ template "repo/fragments/time" $follow.FollowedAt }}</span> 96 150 </div> 97 - {{ template "user/fragments/followCard" 151 + {{ template "user/fragments/followCard" 98 152 (dict 99 153 "LoggedInUser" $root.LoggedInUser 100 154 "UserDid" $follow.SubjectDid

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