forked from tangled.org/core
this repo has no description

clean up timeline

Changed files
+89 -51
appview
+5 -5
appview/db/follow.go
···
type Follow struct {
UserDid string
SubjectDid string
-
FollowedAt *time.Time
+
FollowedAt time.Time
RKey string
}
···
followedAtTime, err := time.Parse(time.RFC3339, followedAt)
if err != nil {
log.Println("unable to determine followed at time")
-
follow.FollowedAt = nil
+
follow.FollowedAt = time.Now()
} else {
-
follow.FollowedAt = &followedAtTime
+
follow.FollowedAt = followedAtTime
}
return &follow, nil
···
followedAtTime, err := time.Parse(time.RFC3339, followedAt)
if err != nil {
log.Println("unable to determine followed at time")
-
follow.FollowedAt = nil
+
follow.FollowedAt = time.Now()
} else {
-
follow.FollowedAt = &followedAtTime
+
follow.FollowedAt = followedAtTime
}
follows = append(follows, follow)
+9 -10
appview/db/repos.go
···
Name string
Knot string
Rkey string
-
Created *time.Time
+
Created time.Time
}
func (d *DB) GetAllRepos() ([]Repo, error) {
var repos []Repo
-
rows, err := d.db.Query(`select * from repos`)
+
rows, err := d.db.Query(`select did, name, knot, rkey, created from repos`)
if err != nil {
return nil, err
}
···
for rows.Next() {
var repo Repo
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, repo.Created)
+
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Created)
if err != nil {
return nil, err
}
···
func (d *DB) GetAllReposByDid(did string) ([]Repo, error) {
var repos []Repo
-
rows, err := d.db.Query(`select did, name, knot, created from repos where did = ?`, did)
+
rows, err := d.db.Query(`select did, name, knot, rkey, created from repos where did = ?`, did)
if err != nil {
return nil, err
}
···
for rows.Next() {
var repo Repo
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, repo.Created)
+
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Created)
if err != nil {
return nil, err
}
···
return nil, err
}
createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
-
repo.Created = &createdAtTime
+
repo.Created = createdAtTime
return &repo, nil
}
···
for rows.Next() {
var repo Repo
-
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, repo.Created)
+
err := scanRepo(rows, &repo.Did, &repo.Name, &repo.Knot, &repo.Rkey, &repo.Created)
if err != nil {
return nil, err
}
···
createdAtTime, err := time.Parse(time.RFC3339, createdAt)
if err != nil {
-
now := time.Now()
-
created = &now
+
*created = time.Now()
} else {
-
created = &createdAtTime
+
*created = createdAtTime
}
return nil
+4 -2
appview/db/timeline.go
···
package db
import (
+
"log"
"sort"
"time"
)
···
type TimelineEvent struct {
*Repo
*Follow
-
EventAt *time.Time
+
EventAt time.Time
}
func (d *DB) MakeTimeline() ([]TimelineEvent, error) {
···
}
for _, repo := range repos {
+
log.Println(repo.Created)
events = append(events, TimelineEvent{
Repo: &repo,
Follow: nil,
···
}
sort.Slice(events, func(i, j int) bool {
-
return events[i].EventAt.After(*events[j].EventAt)
+
return events[i].EventAt.After(events[j].EventAt)
})
return events, nil
+1
appview/pages/pages.go
···
type TimelineParams struct {
LoggedInUser *auth.User
Timeline []db.TimelineEvent
+
DidHandleMap map[string]string
}
func (p *Pages) Timeline(w io.Writer, params TimelineParams) error {
+12 -7
appview/pages/templates/layouts/topbar.html
···
<a href="/repo/new" hx-boost="true" class="{{ $linkstyle }}">
<i class="w-6 h-6" data-lucide="plus"></i>
</a>
-
<a href="/{{ didOrHandle .Did .Handle }}" hx-boost="true" class="{{ $linkstyle }}">
-
{{ didOrHandle .Did .Handle }}
-
</a>
-
<a href="/logout"class="{{ $linkstyle }}">
-
(logout)
-
</a>
+
<details class="relative inline-block text-left">
+
<summary class="{{ $linkstyle }} cursor-pointer list-none">
+
{{ didOrHandle .Did .Handle }}
+
</summary>
+
<div class="absolute flex flex-col right-0 mt-4 p-2 w-48 bg-white border border-black z-50">
+
<a href="/{{ didOrHandle .Did .Handle }}"class="{{ $linkstyle }}">profile</a>
+
<a href="/knots"class="{{ $linkstyle }}">knots</a>
+
<a href="/settings"class="{{ $linkstyle }}">settings</a>
+
<a href="/logout" class="text-red-400 hover:text-red-700 no-underline">logout</a>
+
</div>
+
</details>
{{ else }}
-
<a href="/login" hx-boost="true" class="{{ $linkstyle }}">
+
<a href="/login" class="{{ $linkstyle }}">
login
</a>
{{ end }}
+35 -26
appview/pages/templates/timeline.html
···
<h1>Timeline</h1>
{{ range .Timeline }}
+
<div class="relative
+
px-4
+
py-2
+
border-l
+
border-black
+
before:content-['']
+
before:absolute
+
before:w-1
+
before:h-1
+
before:bg-black
+
before:rounded-full
+
before:left-[-2.2px]
+
before:top-1/2
+
before:-translate-y-1/2
+
">
{{ if .Repo }}
-
<div class="border border-black p-4 m-2 bg-white w-1/2">
-
<div class="flex items-center">
-
<div class="text-sm text-gray-600">
-
{{ .Repo.Did }} created
-
</div>
-
<div class="px-3">{{ .Repo.Name }}</div>
-
</div>
-
-
<time class="text-sm text-gray-700"
-
>{{ .Repo.Created | timeFmt }}</time
-
>
-
</div>
+
{{ $userHandle := index $.DidHandleMap .Repo.Did }}
+
<div class="flex items-center">
+
<p class="text-gray-600">
+
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
+
created
+
<a href="/{{ $userHandle }}/{{ .Repo.Name }}" class="no-underline hover:underline">{{ .Repo.Name }}</a>
+
<time class="text-gray-700">{{ .Repo.Created | timeFmt }}</time>
+
</p>
+
</div>
{{ else if .Follow }}
-
<div class="border border-black p-4 m-2 bg-white w-1/2">
-
<div class="flex items-center">
-
<div class="text-sm text-gray-600">
-
{{ .Follow.UserDid }} followed
-
</div>
-
<div class="text-sm text-gray-800">
-
{{ .Follow.SubjectDid }}
-
</div>
-
</div>
-
-
<time class="text-sm text-gray-700"
-
>{{ .Follow.FollowedAt | timeFmt }}</time
-
>
-
</div>
+
{{ $userHandle := index $.DidHandleMap .Follow.UserDid }}
+
{{ $subjectHandle := index $.DidHandleMap .Follow.SubjectDid }}
+
<div class="flex items-center">
+
<p class="text-gray-600">
+
<a href="/{{ $userHandle }}" class="no-underline hover:underline">{{ $userHandle }}</a>
+
followed
+
<a href="/{{ $subjectHandle }}" class="no-underline hover:underline">{{ $subjectHandle }}</a>
+
<time class="text-gray-700">{{ .Follow.FollowedAt | timeFmt }}</time>
+
</p>
+
</div>
{{ end }}
+
</div>
{{ end }}
{{ end }}
+1 -1
appview/pages/templates/user/profile.html
···
<div class="text-sm mb-4">
<span>{{ .ProfileStats.Followers }} followers</span>
<div class="inline-block px-1 select-none after:content-['·']"></div>
-
<span>following {{ .ProfileStats.Following }}</span>
+
<span>{{ .ProfileStats.Following }} following</span>
</div>
<p class="text-xs font-bold py-2">REPOS</p>
<div id="repos" class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
+22
appview/state/state.go
···
s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.")
}
+
var didsToResolve []string
+
for _, ev := range timeline {
+
if ev.Repo != nil {
+
didsToResolve = append(didsToResolve, ev.Repo.Did)
+
}
+
if ev.Follow != nil {
+
didsToResolve = append(didsToResolve, ev.Follow.UserDid)
+
didsToResolve = append(didsToResolve, ev.Follow.SubjectDid)
+
}
+
}
+
+
resolvedIds := s.resolver.ResolveIdents(r.Context(), didsToResolve)
+
didHandleMap := make(map[string]string)
+
for _, identity := range resolvedIds {
+
if !identity.Handle.IsInvalidHandle() {
+
didHandleMap[identity.DID.String()] = fmt.Sprintf("@%s", identity.Handle.String())
+
} else {
+
didHandleMap[identity.DID.String()] = identity.DID.String()
+
}
+
}
+
s.pages.Timeline(w, pages.TimelineParams{
LoggedInUser: user,
Timeline: timeline,
+
DidHandleMap: didHandleMap,
})
return