Show pinned tweets in the web UI

This commit is contained in:
Alessio 2024-03-18 21:30:01 -07:00
parent ca7cf613f9
commit 41e525d223
7 changed files with 46 additions and 12 deletions

View File

@ -1,10 +1,11 @@
#define NAME "Offline Twitter"
#define EXE_NAME "twitter.exe"
; The `version` macro should be passed from command line using `/Dversion=[...]`
[Setup]
AppName={#NAME}
AppVersion={#VERSION}
AppVersion={#version}
WizardStyle=modern
DefaultDirName={autopf}/offline-twitter
DefaultGroupName={#NAME}

View File

@ -91,6 +91,7 @@ func (app *Application) UserFeed(w http.ResponseWriter, r *http.Request) {
data := struct {
persistence.Feed
scraper.UserID
PinnedTweet scraper.Tweet
FeedType string
}{Feed: feed, UserID: user.ID}
@ -100,6 +101,16 @@ func (app *Application) UserFeed(w http.ResponseWriter, r *http.Request) {
data.FeedType = ""
}
// Add a pinned tweet if there is one and it's in the DB; otherwise skip
if user.PinnedTweetID != scraper.TweetID(0) && len(parts) <= 1 || parts[1] == "without_replies" {
data.PinnedTweet, err = app.Profile.GetTweetById(user.PinnedTweetID)
if err == nil {
feed.TweetTrove.Tweets[data.PinnedTweet.ID] = data.PinnedTweet
} else if !errors.Is(err, persistence.ErrNotInDB) {
panic(err)
}
}
if r.Header.Get("HX-Request") == "true" && c.CursorPosition == persistence.CURSOR_MIDDLE {
// It's a Show More request
app.buffered_render_htmx(w, "timeline", PageGlobalData{TweetTrove: feed.TweetTrove}, data)

View File

@ -81,10 +81,9 @@ func TestUserFeed(t *testing.T) {
title_node := cascadia.Query(root, selector("title"))
assert.Equal(title_node.FirstChild.Data, "@Cernovich | Offline Twitter")
tweet_nodes := cascadia.QueryAll(root, selector(".timeline > .tweet"))
assert.Len(tweet_nodes, 7)
including_quote_tweets := cascadia.QueryAll(root, selector(".tweet"))
assert.Len(including_quote_tweets, 10)
assert.Len(cascadia.QueryAll(root, selector(".timeline > .tweet")), 8)
assert.Len(cascadia.QueryAll(root, selector(".timeline > .pinned-tweet")), 1)
assert.Len(cascadia.QueryAll(root, selector(".tweet")), 12) // Pinned tweet appears again
}
func TestUserFeedWithEntityInBio(t *testing.T) {
@ -224,7 +223,7 @@ func TestTimeline(t *testing.T) {
assert.Equal(title_node.FirstChild.Data, "Timeline | Offline Twitter")
tweet_nodes := cascadia.QueryAll(root, selector(".timeline > .tweet"))
assert.Len(tweet_nodes, 18)
assert.Len(tweet_nodes, 19)
}
func TestTimelineWithCursor(t *testing.T) {

View File

@ -343,6 +343,18 @@ h3 {
color: var(--color-twitter-blue);
}
.pinned-tweet__pin-container {
margin: 0.5em 0em -1em 3em;
z-index: 1;
position: relative; /* z-index is ignored if `position` is "static" */
gap: 0.2em;
}
img.svg-icon.pinned-tweet__pin-icon {
filter: invert(43%) saturate(30%);
width: 1em;
height: auto;
}
.row {
display: flex;
flex-direction: row;
@ -474,7 +486,7 @@ ul.quick-links {
padding-top: 0.8em;
padding-bottom: 0.8em;
}
.timeline > .tweet {
.timeline > .tweet, .timeline > .pinned-tweet {
/* not for nested (i.e., quoted) tweets */
border-bottom: 1px solid var(--color-twitter-off-white-dark);
}

View File

@ -22,6 +22,15 @@
</div>
<div class="timeline user-feed-timeline">
{{if .PinnedTweet.ID}}
<div class="pinned-tweet">
<div class="row pinned-tweet__pin-container">
<img class="svg-icon pinned-tweet__pin-icon" src="/static/icons/pin.svg" width="24" height="24" />
<span>Pinned</span>
</div>
{{template "tweet" (dict "TweetID" .PinnedTweet.ID "RetweetID" 0)}}
</div>
{{end}}
{{template "timeline" .}}
</div>
{{end}}

View File

@ -207,10 +207,11 @@ func TestSearchDateFilters(t *testing.T) {
c.UntilTimestamp.Time = time.Date(2021, 10, 1, 0, 0, 0, 0, time.UTC)
feed, err = profile.NextPage(c, UserID(0))
require.NoError(err)
assert.Len(feed.Items, 3)
assert.Equal(feed.Items[0].TweetID, TweetID(1439027915404939265))
assert.Equal(feed.Items[1].TweetID, TweetID(1439068749336748043))
assert.Equal(feed.Items[2].TweetID, TweetID(1439067163508150272))
assert.Len(feed.Items, 4)
assert.Equal(feed.Items[0].TweetID, TweetID(1439747634277740546))
assert.Equal(feed.Items[1].TweetID, TweetID(1439027915404939265))
assert.Equal(feed.Items[2].TweetID, TweetID(1439068749336748043))
assert.Equal(feed.Items[3].TweetID, TweetID(1439067163508150272))
}
func TestSearchMediaFilters(t *testing.T) {

View File

@ -175,6 +175,7 @@ INSERT INTO tweets VALUES
(2857357,1489944024278523906,96906231,'According to @gofundme it was "as a result of multiple discussions with locals law enforcement and *police reports of violence and other unlawful activity*". ABSOLUTE LIES! I asked police officers live and they CONFIRMED there was no violence. Pure censorship. #BankruptGoFundMe',1644065311000,5753,2127,219,110,0,0,'gofundme','','BankruptGoFundMe',NULL,NULL,0,1,0,0,0),
(121936,1513313535480287235,1178839081222115328,'Smh wish I could RT',1649637037000,4,0,1,0,1513312559981551619,0,'PublicAnthony','PublicAnthony','',NULL,NULL,0,1,0,0,0),
(869468,1624833173514293249,1240784920831762433,'',1676225391000,1,0,0,0,0,0,'','','','1OwGWwnoleRGQ',NULL,0,1,0,0,0),
(2090918,1439747634277740546,358545917,'Explain why staff but not talent at these events have to wear masks. Using science.',1632097559000,29832,4145,783,163,0,0,'','','',NULL,NULL,0,1,1,1710818767264,0),
(2857431,1695110851324256692,19370504,replace('My dad was a doctor, he retired this past year \n\nHes been healthy his whole life, and he saw the titanic shift (no pun intended) in obesity being normalized in real time \n\nIt used to be a 300lb person was uncommon \n\nThen it was 400lbs\n\nThen 500lbs\n\nHospitals had to upgrade their scales to veterinary scales they use in zoos,\nThats how fat people became \n\nObese patients would be OFFENDED if you suggested they lose weight \n\nThey would complain if you told them their back pain was because their BMI was 45 \n\nTheyd ignore all suggestions of exercise or diet and complain why cant they just take a pill \n\nThis wasnt outliers, this is at least 50% of the population \n\nUntil you work with general public, you cannot fully conceive the existent of peoples sloth and apathy towards their own quality of life','\n',char(10)),1692980895000,1894,224,137,25,0,0,'','','',NULL,NULL,0,1,1,1693055764000,1),
(1405789,1698426460061487546,1458284524761075714,'Zig''s "comptime" leads to the most elegant reflection code I''ve ever seen. It''s much cleaner and more expressive than, e.g., Python''s various __methods__, or worse, the deranged "metaclasses" nonsense; but it also has no runtime cost!',1693771397000,6,0,1,1,0,1692962678824648811,'','','',NULL,NULL,0,1,0,0,0),
(1408662,1698762403163304110,1458284524761075714,replace('Another very cool use of Zig''s "comptime" is it lets you write real, compiled mini-languages in strings; e.g.:\n\n- SQL prepared statements\n- "printf" style format strings\n- regexps\n\nEvery language uses these, but they''re interpreted at runtime, even in compiled languages.','\n',char(10)),1693851493000,7,2,3,0,0,1698426460061487546,'','','',NULL,NULL,0,1,0,0,0),