Implement 'likes sort order' for Likes tab
This commit is contained in:
parent
9aff2b8a93
commit
dc1bde2fe6
@ -155,13 +155,40 @@ func TestUserLikesFeed(t *testing.T) {
|
||||
|
||||
// Fetch @Peter_Nimitz user feed while logged in as @MysteryGrove
|
||||
c := persistence.NewUserFeedLikesCursor(UserHandle("MysteryGrove"))
|
||||
require.Equal(c.SortOrder, persistence.SORT_ORDER_LIKED_AT)
|
||||
c.PageSize = 2
|
||||
feed, err := profile.NextPage(c, UserID(0))
|
||||
require.NoError(err)
|
||||
|
||||
// Should have "liked" 1 tweet
|
||||
require.Len(feed.Tweets, 2)
|
||||
for i, expected_tweet_id := range []TweetID{1698765208393576891, 1426669666928414720} {
|
||||
assert.Equal(feed.Items[i].TweetID, expected_tweet_id)
|
||||
_, is_ok := feed.Tweets[expected_tweet_id]
|
||||
assert.True(is_ok)
|
||||
}
|
||||
|
||||
require.Equal(feed.CursorBottom.CursorValue, 4)
|
||||
feed, err = profile.NextPage(feed.CursorBottom, UserID(0))
|
||||
require.NoError(err)
|
||||
|
||||
require.Len(feed.Tweets, 2)
|
||||
for i, expected_tweet_id := range []TweetID{1343633011364016128, 1513313535480287235} {
|
||||
assert.Equal(feed.Items[i].TweetID, expected_tweet_id)
|
||||
_, is_ok := feed.Tweets[expected_tweet_id]
|
||||
assert.True(is_ok)
|
||||
}
|
||||
|
||||
assert.Equal(feed.CursorBottom.CursorValue, 2)
|
||||
feed, err = profile.NextPage(feed.CursorBottom, UserID(0))
|
||||
require.NoError(err)
|
||||
|
||||
require.Len(feed.Tweets, 1)
|
||||
_, is_ok := feed.Tweets[1413646595493568516]
|
||||
assert.True(is_ok)
|
||||
for i, expected_tweet_id := range []TweetID{1413646595493568516} {
|
||||
assert.Equal(feed.Items[i].TweetID, expected_tweet_id)
|
||||
_, is_ok := feed.Tweets[expected_tweet_id]
|
||||
assert.True(is_ok)
|
||||
}
|
||||
assert.Equal(feed.CursorBottom.CursorPosition, persistence.CURSOR_END)
|
||||
}
|
||||
|
||||
func TestTweetDetailWithReplies(t *testing.T) {
|
||||
|
@ -16,6 +16,7 @@ const (
|
||||
SORT_ORDER_OLDEST
|
||||
SORT_ORDER_MOST_LIKES
|
||||
SORT_ORDER_MOST_RETWEETS
|
||||
SORT_ORDER_LIKED_AT
|
||||
)
|
||||
|
||||
func (o SortOrder) OrderByClause() string {
|
||||
@ -28,6 +29,8 @@ func (o SortOrder) OrderByClause() string {
|
||||
return "order by num_likes desc"
|
||||
case SORT_ORDER_MOST_RETWEETS:
|
||||
return "order by num_retweets desc"
|
||||
case SORT_ORDER_LIKED_AT:
|
||||
return "order by likes_sort_order desc"
|
||||
default:
|
||||
panic(fmt.Sprintf("Invalid sort order: %d", o))
|
||||
}
|
||||
@ -42,6 +45,8 @@ func (o SortOrder) PaginationWhereClause() string {
|
||||
return "num_likes < ?"
|
||||
case SORT_ORDER_MOST_RETWEETS:
|
||||
return "num_retweets < ?"
|
||||
case SORT_ORDER_LIKED_AT:
|
||||
return "likes_sort_order < ?"
|
||||
default:
|
||||
panic(fmt.Sprintf("Invalid sort order: %d", o))
|
||||
}
|
||||
@ -56,6 +61,8 @@ func (o SortOrder) NextCursorValue(r CursorResult) int {
|
||||
return r.NumLikes
|
||||
case SORT_ORDER_MOST_RETWEETS:
|
||||
return r.NumRetweets
|
||||
case SORT_ORDER_LIKED_AT:
|
||||
return r.LikeSortOrder
|
||||
default:
|
||||
panic(fmt.Sprintf("Invalid sort order: %d", o))
|
||||
}
|
||||
@ -94,8 +101,9 @@ const (
|
||||
type CursorResult struct {
|
||||
scraper.Tweet
|
||||
scraper.Retweet
|
||||
Chrono int `db:"chrono"`
|
||||
ByUserID scraper.UserID `db:"by_user_id"`
|
||||
Chrono int `db:"chrono"`
|
||||
LikeSortOrder int `db:"likes_sort_order"`
|
||||
ByUserID scraper.UserID `db:"by_user_id"`
|
||||
}
|
||||
|
||||
type Cursor struct {
|
||||
@ -181,7 +189,7 @@ func NewUserFeedLikesCursor(h scraper.UserHandle) Cursor {
|
||||
UntilTimestamp: scraper.TimestampFromUnix(0),
|
||||
CursorPosition: CURSOR_START,
|
||||
CursorValue: 0,
|
||||
SortOrder: SORT_ORDER_NEWEST,
|
||||
SortOrder: SORT_ORDER_LIKED_AT,
|
||||
PageSize: 50,
|
||||
|
||||
LikedByUserHandle: h,
|
||||
@ -255,6 +263,8 @@ func (c *Cursor) apply_token(token string) error {
|
||||
c.ToUserHandles = append(c.ToUserHandles, scraper.UserHandle(parts[1]))
|
||||
case "retweeted_by":
|
||||
c.RetweetedByUserHandle = scraper.UserHandle(parts[1])
|
||||
case "liked_by":
|
||||
c.LikedByUserHandle = scraper.UserHandle(parts[1])
|
||||
case "since":
|
||||
c.SinceTimestamp.Time, err = time.Parse("2006-01-02", parts[1])
|
||||
case "until":
|
||||
@ -396,10 +406,16 @@ func (p Profile) NextPage(c Cursor, current_user_id scraper.UserID) (Feed, error
|
||||
}
|
||||
|
||||
liked_by_filter_join_clause := ""
|
||||
likes_sort_order_field := ""
|
||||
if c.LikedByUserHandle != "" {
|
||||
liked_by_filter_join_clause = " join likes filter_likes on tweets.id = filter_likes.tweet_id "
|
||||
where_clauses = append(where_clauses, "filter_likes.user_id = (select id from users where handle like ?) ")
|
||||
bind_values = append(bind_values, c.LikedByUserHandle)
|
||||
likes_sort_order_field = ", coalesce(filter_likes.sort_order, -1) likes_sort_order "
|
||||
|
||||
// Don't include retweets on "liked by" searches because it doesn't distinguish which retweet
|
||||
// version was the "liked" one
|
||||
where_clauses = append(where_clauses, "retweet_id = 0")
|
||||
}
|
||||
|
||||
// Pagination
|
||||
@ -414,7 +430,7 @@ func (p Profile) NextPage(c Cursor, current_user_id scraper.UserID) (Feed, error
|
||||
}
|
||||
|
||||
q := `select * from (
|
||||
select ` + TWEETS_ALL_SQL_FIELDS + `,
|
||||
select ` + TWEETS_ALL_SQL_FIELDS + likes_sort_order_field + `,
|
||||
0 tweet_id, 0 retweet_id, 0 retweeted_by, 0 retweeted_at,
|
||||
posted_at chrono, tweets.user_id by_user_id
|
||||
from tweets
|
||||
@ -427,7 +443,7 @@ func (p Profile) NextPage(c Cursor, current_user_id scraper.UserID) (Feed, error
|
||||
union
|
||||
|
||||
select * from (
|
||||
select ` + TWEETS_ALL_SQL_FIELDS + `,
|
||||
select ` + TWEETS_ALL_SQL_FIELDS + likes_sort_order_field + `,
|
||||
retweets.tweet_id, retweet_id, retweeted_by, retweeted_at,
|
||||
retweeted_at chrono, retweeted_by by_user_id
|
||||
from retweets
|
||||
|
@ -190,10 +190,6 @@ create table hashtags (rowid integer primary key,
|
||||
foreign key(tweet_id) references tweets(id)
|
||||
);
|
||||
|
||||
create table database_version(rowid integer primary key,
|
||||
version_number integer not null unique
|
||||
);
|
||||
|
||||
create table likes(rowid integer primary key,
|
||||
sort_order integer unique not null,
|
||||
user_id integer not null,
|
||||
@ -202,6 +198,12 @@ create table likes(rowid integer primary key,
|
||||
foreign key(user_id) references users(id)
|
||||
foreign key(tweet_id) references tweets(id)
|
||||
);
|
||||
create index if not exists index_likes_user_id on likes (user_id);
|
||||
create index if not exists index_likes_tweet_id on likes (tweet_id);
|
||||
|
||||
create table fake_user_sequence(latest_fake_id integer not null);
|
||||
insert into fake_user_sequence values(0x4000000000000000);
|
||||
|
||||
create table database_version(rowid integer primary key,
|
||||
version_number integer not null unique
|
||||
);
|
||||
|
@ -307,6 +307,11 @@ create table likes(rowid integer primary key,
|
||||
foreign key(tweet_id) references tweets(id)
|
||||
);
|
||||
insert into likes values(1, 1, 1178839081222115328, 1413646595493568516);
|
||||
insert into likes values(2, 2, 1178839081222115328, 1513313535480287235);
|
||||
insert into likes values(3, 3, 1178839081222115328, 1343633011364016128);
|
||||
insert into likes values(4, 4, 1178839081222115328, 1426669666928414720);
|
||||
insert into likes values(5, 5, 1178839081222115328, 1698765208393576891);
|
||||
|
||||
|
||||
create table fake_user_sequence(latest_fake_id integer not null);
|
||||
insert into fake_user_sequence values(0x4000000000000000);
|
||||
|
Loading…
x
Reference in New Issue
Block a user