Add rendering of Spaces
This commit is contained in:
parent
a12dcae4e4
commit
2078eb8026
@ -45,6 +45,7 @@ type TweetCollection interface {
|
||||
Tweet(id scraper.TweetID) scraper.Tweet
|
||||
User(id scraper.UserID) scraper.User
|
||||
Retweet(id scraper.TweetID) scraper.Retweet
|
||||
Space(id scraper.SpaceID) scraper.Space
|
||||
FocusedTweetID() scraper.TweetID
|
||||
}
|
||||
|
||||
@ -62,6 +63,7 @@ func (app *Application) buffered_render_tweet_page(w http.ResponseWriter, tpl_fi
|
||||
"tweet": data.Tweet,
|
||||
"user": data.User,
|
||||
"retweet": data.Retweet,
|
||||
"space": data.Space,
|
||||
"active_user": app.get_active_user,
|
||||
"focused_tweet_id": data.FocusedTweetID,
|
||||
}),
|
||||
@ -99,6 +101,7 @@ func (app *Application) buffered_render_tweet_htmx(w http.ResponseWriter, tpl_na
|
||||
"tweet": data.Tweet,
|
||||
"user": data.User,
|
||||
"retweet": data.Retweet,
|
||||
"space": data.Space,
|
||||
"active_user": app.get_active_user,
|
||||
"focused_tweet_id": data.FocusedTweetID,
|
||||
}),
|
||||
|
@ -172,6 +172,9 @@ func (t TweetDetailData) User(id scraper.UserID) scraper.User {
|
||||
func (t TweetDetailData) Retweet(id scraper.TweetID) scraper.Retweet {
|
||||
return t.Retweets[id]
|
||||
}
|
||||
func (t TweetDetailData) Space(id scraper.SpaceID) scraper.Space {
|
||||
return t.Spaces[id]
|
||||
}
|
||||
func (t TweetDetailData) FocusedTweetID() scraper.TweetID {
|
||||
return t.MainTweetID
|
||||
}
|
||||
@ -254,7 +257,9 @@ func (t UserProfileData) User(id scraper.UserID) scraper.User {
|
||||
func (t UserProfileData) Retweet(id scraper.TweetID) scraper.Retweet {
|
||||
return t.Retweets[id]
|
||||
}
|
||||
|
||||
func (t UserProfileData) Space(id scraper.SpaceID) scraper.Space {
|
||||
return t.Spaces[id]
|
||||
}
|
||||
func (t UserProfileData) FocusedTweetID() scraper.TweetID {
|
||||
return scraper.TweetID(0)
|
||||
}
|
||||
|
@ -217,6 +217,14 @@ func TestTweetsWithContent(t *testing.T) {
|
||||
root, err = html.Parse(resp.Body)
|
||||
require.NoError(err)
|
||||
assert.Len(cascadia.QueryAll(root, selector(".embedded-link")), 3)
|
||||
|
||||
// Space
|
||||
resp = do_request(httptest.NewRequest("GET", "/tweet/1624833173514293249", nil))
|
||||
require.Equal(resp.StatusCode, 200)
|
||||
root, err = html.Parse(resp.Body)
|
||||
require.NoError(err)
|
||||
assert.Len(cascadia.QueryAll(root, selector(".space")), 1)
|
||||
assert.Len(cascadia.QueryAll(root, selector("ul.space-participants-list li")), 9)
|
||||
}
|
||||
|
||||
// Follow and unfollow
|
||||
|
@ -6,6 +6,9 @@
|
||||
--color-twitter-off-white-dark: #dae5e5; /* hsv(180, 4.8, 89.8) */
|
||||
--color-outline-gray: #dcdcdc;
|
||||
|
||||
--color-space-purple: #a49bfd;
|
||||
--color-space-purple-outline: #6452fc;
|
||||
|
||||
/*
|
||||
const QColor COLOR_OUTLINE_GRAY = QColor(220, 220, 220);
|
||||
const QColor COLOR_TWITTER_BLUE = QColor(27, 149, 224);
|
||||
@ -48,6 +51,20 @@ input, select {
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
ul.inline-dotted-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
ul.inline-dotted-list li {
|
||||
display: inline;
|
||||
}
|
||||
ul.inline-dotted-list li:after {
|
||||
content: " ⋅";
|
||||
}
|
||||
ul.inline-dotted-list li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.tweet {
|
||||
padding: 0 1.5em;
|
||||
}
|
||||
@ -118,20 +135,10 @@ input, select {
|
||||
margin: 0 5em;
|
||||
cursor: default;
|
||||
}
|
||||
ul.reply-mentions {
|
||||
list-style: none;
|
||||
.reply-mentions {
|
||||
padding: 0 0.5em;
|
||||
margin: 0;
|
||||
}
|
||||
ul.reply-mentions li {
|
||||
display: inline;
|
||||
}
|
||||
ul.reply-mentions li:after {
|
||||
content: " ⋅";
|
||||
}
|
||||
ul.reply-mentions li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.replying-to-label {
|
||||
color: var(--color-twitter-text-gray);
|
||||
}
|
||||
@ -170,7 +177,7 @@ img.embedded-link-preview {
|
||||
font-size: 0.8em;
|
||||
margin: 0;
|
||||
}
|
||||
.embedded-link-title {
|
||||
h3 {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
.embedded-link-domain-container {
|
||||
@ -474,15 +481,52 @@ input[type="submit"] {
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
.poll-choice-label {
|
||||
/* flex-grow: 1;*/
|
||||
width: 50%;
|
||||
}
|
||||
.poll-choice-votes {
|
||||
width: 50%;
|
||||
/* flex-grow: 1;*/
|
||||
}
|
||||
.poll-metadata {
|
||||
color: var(--color-twitter-text-gray);
|
||||
margin: 0;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.space {
|
||||
outline: 1px solid var(--color-space-purple-outline);
|
||||
background-color: var(--color-space-purple);
|
||||
border-radius: 1.5em;
|
||||
padding: 1.5em;
|
||||
}
|
||||
.space-title {
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
.space .host-label {
|
||||
color: var(--color-space-purple-outline);
|
||||
}
|
||||
.space-date {
|
||||
color: var(--color-space-purple-outline);
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.space-info-list {
|
||||
padding: 0;
|
||||
}
|
||||
.space .layout-spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
ul.space-participants-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
ul.space-participants-list li {
|
||||
padding: 0.5em 0;
|
||||
display: inline-block;
|
||||
width: 24%;
|
||||
}
|
||||
.space-participants-list .author-info {
|
||||
font-size: 0.9em;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
.space-participants-list .author-info .profile-image {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
{{if $main_tweet.ReplyMentions}}
|
||||
<div class="reply-mentions-container" hx-trigger="click consume">
|
||||
<span class="replying-to-label">Replying to</span>
|
||||
<ul class="reply-mentions">
|
||||
<ul class="reply-mentions inline-dotted-list">
|
||||
{{range $main_tweet.ReplyMentions}}
|
||||
<li><a class="entity" href="/{{.}}">@{{.}}</a></li>
|
||||
{{end}}
|
||||
@ -88,6 +88,9 @@
|
||||
{{template "tweet" (dict "TweetID" $main_tweet.QuotedTweetID "RetweetID" 0 "QuoteNestingLevel" (add .QuoteNestingLevel 1))}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{if $main_tweet.SpaceID}}
|
||||
{{template "space" (space $main_tweet.SpaceID)}}
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="interactions-bar">
|
||||
|
34
internal/webserver/tpl/tweet_page_includes/space.tpl
Normal file
34
internal/webserver/tpl/tweet_page_includes/space.tpl
Normal file
@ -0,0 +1,34 @@
|
||||
{{define "space"}}
|
||||
<div class="space">
|
||||
<div class="space-host row">
|
||||
{{template "author-info" (user .CreatedById)}}
|
||||
<span class="host-label">(Host)</span>
|
||||
<div class="layout-spacer"></div>
|
||||
<div class="space-date">
|
||||
{{.StartedAt.Format "Jan 2, 2006"}}<br>{{.StartedAt.Format "3:04pm"}}
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="space-title">{{.Title}}</h3>
|
||||
<div class="space-info row">
|
||||
<span class="space-state">
|
||||
{{if (eq .State "Ended")}}
|
||||
<ul class="space-info-list inline-dotted-list">
|
||||
<li>{{.State}}</li>
|
||||
<li>{{(len .ParticipantIds)}} participants</li>
|
||||
<li>{{.LiveListenersCount}} tuned in</li>
|
||||
<li>Lasted {{.FormatDuration}}</li>
|
||||
</ul>
|
||||
{{else}}
|
||||
{{.State}}
|
||||
{{end}}
|
||||
</span>
|
||||
</div>
|
||||
<ul class="space-participants-list">
|
||||
{{range .ParticipantIds}}
|
||||
{{if (ne . $.CreatedById)}}
|
||||
<li>{{template "author-info" (user .)}}</li>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
@ -45,6 +45,33 @@ func (p Profile) fill_content(trove *TweetTrove) {
|
||||
}
|
||||
}
|
||||
|
||||
space_ids := []interface{}{}
|
||||
for _, t := range trove.Tweets {
|
||||
if t.SpaceID != "" {
|
||||
space_ids = append(space_ids, t.SpaceID)
|
||||
}
|
||||
}
|
||||
if len(space_ids) > 0 {
|
||||
var spaces []Space
|
||||
err := p.DB.Select(&spaces, `
|
||||
select id, created_by_id, short_url, state, title, created_at, started_at, ended_at, updated_at, is_available_for_replay,
|
||||
replay_watch_count, live_listeners_count, is_details_fetched
|
||||
from spaces
|
||||
where id in (`+strings.Repeat("?,", len(space_ids)-1)+`?)`,
|
||||
space_ids...,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, s := range spaces {
|
||||
err := p.DB.Select(&s.ParticipantIds, "select user_id from space_participants where space_id = ?", s.ID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
trove.Spaces[s.ID] = s
|
||||
}
|
||||
}
|
||||
|
||||
in_clause := ""
|
||||
user_ids := []interface{}{}
|
||||
tweet_ids := []interface{}{}
|
||||
@ -58,6 +85,12 @@ func (p Profile) fill_content(trove *TweetTrove) {
|
||||
for _, r := range trove.Retweets {
|
||||
user_ids = append(user_ids, int(r.RetweetedByID))
|
||||
}
|
||||
for _, s := range trove.Spaces {
|
||||
user_ids = append(user_ids, s.CreatedById)
|
||||
for _, p := range s.ParticipantIds {
|
||||
user_ids = append(user_ids, p)
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the users
|
||||
if len(user_ids) > 0 { // It could be a search with no results, end of feed, etc-- strings.Repeat will fail!
|
||||
|
Loading…
x
Reference in New Issue
Block a user