diff --git a/doc/TODO.txt b/doc/TODO.txt index 8fc051c..7609a4b 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -79,7 +79,6 @@ TODO: mobile-requests - implement mobile versions of various requests - Check in `pkg/scraper/test_responses/mobile_requests` - TODO: search-bottom-cursor - Entry type "TimelineReplaceEntries" that replaces the cursor in the timeline instead of the new timeline having a new one - As first step, need helper function that returns the []Instruction element in a APIV2Response (not just the MainInstruction which is TimelineAddEntries) @@ -103,7 +102,6 @@ TODO: login-routes-tests TODO: web-ui-downloading - web UI needs buttons to trigger a scrape / refresh manually - - user feed - timeline TODO: webserver-session-arg-active-user @@ -121,5 +119,8 @@ TODO: image-width-and-height - Images should have explicit "width" and "height" attributes. This reduces Cumulative Layout Shift (CLS) while loading the page. - https://web.dev/optimize-cls/#images-without-dimensions -TODO: quote-tweet-icon -- show quote-tweets on a tweet +TODO: download-buttons-not-ugly +- Make the options buttons for downloading less ugly (rn they are ugly) + +TODO: show-errors-in-UI +- if an HTTP request fails, show an error in the UI somehow diff --git a/internal/webserver/handler_user_feed.go b/internal/webserver/handler_user_feed.go index 185896f..1069d4d 100644 --- a/internal/webserver/handler_user_feed.go +++ b/internal/webserver/handler_user_feed.go @@ -34,9 +34,6 @@ func (app *Application) UserFeed(w http.ResponseWriter, r *http.Request) { app.traceLog.Printf("'UserFeed' handler (path: %q)", r.URL.Path) parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/") - if len(parts) != 1 { - app.error_404(w) - } user, err := app.Profile.GetUserByHandle(scraper.UserHandle(parts[0])) if err != nil { @@ -44,6 +41,21 @@ func (app *Application) UserFeed(w http.ResponseWriter, r *http.Request) { return } + if len(parts) == 2 && parts[1] == "scrape" { + if app.IsScrapingDisabled { + http.Error(w, "Scraping is disabled (are you logged in?)", 401) + return + } + + // Run scraper + trove, err := scraper.GetUserFeedGraphqlFor(user.ID, 50) // TODO: parameterizable + if err != nil { + app.ErrorLog.Print(err) + // TOOD: show error in UI + } + app.Profile.SaveTweetTrove(trove) + } + c := persistence.NewUserFeedCursor(user.Handle) err = parse_cursor_value(&c, r) if err != nil { diff --git a/internal/webserver/static/icons/quote.svg b/internal/webserver/static/icons/quote.svg new file mode 100644 index 0000000..4e4eaf3 --- /dev/null +++ b/internal/webserver/static/icons/quote.svg @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/internal/webserver/static/styles.css b/internal/webserver/static/styles.css index 5c074d8..e277106 100644 --- a/internal/webserver/static/styles.css +++ b/internal/webserver/static/styles.css @@ -546,6 +546,7 @@ ul.dropdown-items { position: absolute; top: 2em; width: fit-content; + margin: 0; padding: 0.3em; background-color: var(--color-twitter-off-white); outline: 1px solid var(--color-outline-gray); diff --git a/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl b/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl index fa712ef..8957c08 100644 --- a/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl +++ b/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl @@ -91,10 +91,10 @@