diff --git a/internal/webserver/response_helpers.go b/internal/webserver/response_helpers.go index e5b6a19..8c1de5b 100644 --- a/internal/webserver/response_helpers.go +++ b/internal/webserver/response_helpers.go @@ -56,6 +56,7 @@ func (app *Application) buffered_render(w http.ResponseWriter, tpl *template.Tem type TweetCollection interface { Tweet(id scraper.TweetID) scraper.Tweet User(id scraper.UserID) scraper.User + Retweet(id scraper.TweetID) scraper.Retweet FocusedTweetID() scraper.TweetID } @@ -72,6 +73,7 @@ func (app *Application) buffered_render_tweet_page(w http.ResponseWriter, tpl_fi func_map(template.FuncMap{ "tweet": data.Tweet, "user": data.User, + "retweet": data.Retweet, "active_user": app.get_active_user, "focused_tweet_id": data.FocusedTweetID, }), diff --git a/internal/webserver/server.go b/internal/webserver/server.go index 1ea07df..bb0fe73 100644 --- a/internal/webserver/server.go +++ b/internal/webserver/server.go @@ -138,6 +138,9 @@ func (t TweetDetailData) Tweet(id scraper.TweetID) scraper.Tweet { func (t TweetDetailData) User(id scraper.UserID) scraper.User { return t.Users[id] } +func (t TweetDetailData) Retweet(id scraper.TweetID) scraper.Retweet { + return t.Retweets[id] +} func (t TweetDetailData) FocusedTweetID() scraper.TweetID { return t.MainTweetID } @@ -217,6 +220,10 @@ func (t UserProfileData) Tweet(id scraper.TweetID) scraper.Tweet { func (t UserProfileData) User(id scraper.UserID) scraper.User { return t.Users[id] } +func (t UserProfileData) Retweet(id scraper.TweetID) scraper.Retweet { + return t.Retweets[id] +} + func (t UserProfileData) FocusedTweetID() scraper.TweetID { return scraper.TweetID(0) } diff --git a/internal/webserver/static/styles.css b/internal/webserver/static/styles.css index 6ab3826..1a00d37 100644 --- a/internal/webserver/static/styles.css +++ b/internal/webserver/static/styles.css @@ -385,3 +385,17 @@ input[type="submit"] { .quick-link .author-info { pointer-events: none; } +.retweet-info-container { + margin-left: 3.5em; + display: flex; + align-items: center; + opacity: 0.8; +} +.retweet-info-container .svg-icon { + width: 1.2em; /* override default from .svg-icon of 1.5em */ + opacity: 0.6; + margin-right: 0.3em; +} +.retweeted-by-label { + margin: 0 0.2em; +} diff --git a/internal/webserver/tpl/tweet_detail.tpl b/internal/webserver/tpl/tweet_detail.tpl index 8dcdf9c..0a0e21f 100644 --- a/internal/webserver/tpl/tweet_detail.tpl +++ b/internal/webserver/tpl/tweet_detail.tpl @@ -4,18 +4,18 @@ {{define "main"}} {{range .ParentIDs}}
- {{template "tweet" .}} + {{template "tweet" (dict "TweetID" . "RetweetID" 0)}}
{{end}}
- {{template "tweet" .MainTweetID}} + {{template "tweet" (dict "TweetID" .MainTweetID "RetweetID" 0)}}
{{range .ReplyChains}}
{{range .}}
- {{template "tweet" .}} + {{template "tweet" (dict "TweetID" . "RetweetID" 0)}}
{{end}}
diff --git a/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl b/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl index 012457b..5e675c1 100644 --- a/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl +++ b/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl @@ -1,5 +1,5 @@ {{define "tweet"}} -{{$main_tweet := (tweet .)}} +{{$main_tweet := (tweet .TweetID)}} {{$author := (user $main_tweet.UserID)}}
+ {{if (not (eq .RetweetID 0))}} + {{$retweet := (retweet .RetweetID)}} + {{$retweet_user := (user $retweet.RetweetedByID)}} +
+ + Retweeted by + + {{$retweet_user.DisplayName}} + +
+ {{end}}
{{template "author-info" $author}} diff --git a/pkg/scraper/tweet.go b/pkg/scraper/tweet.go index 74cc7b8..c28894e 100644 --- a/pkg/scraper/tweet.go +++ b/pkg/scraper/tweet.go @@ -36,9 +36,7 @@ func (l CommaSeparatedList) Value() (driver.Value, error) { } type Tweet struct { - ID TweetID `db:"id"` - UserID UserID `db:"user_id"` - User *User + ID TweetID `db:"id"` Text string `db:"text"` IsExpandable bool `db:"is_expandable"` PostedAt Timestamp `db:"posted_at"` @@ -49,6 +47,9 @@ type Tweet struct { InReplyToID TweetID `db:"in_reply_to_id"` QuotedTweetID TweetID `db:"quoted_tweet_id"` + UserID UserID `db:"user_id"` + User *User `db:"user"` + // For processing tombstones UserHandle UserHandle in_reply_to_user_handle UserHandle