diff --git a/doc/TODO.txt b/doc/TODO.txt
index d0a27b4..bec4679 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -97,8 +97,8 @@ TOOD: login-routes-tests
TODO: web-ui-downloading
- web UI needs buttons to trigger a scrape / refresh manually
-
-TODO: web-ui-search
+ - user feed
+ - timeline
TODO: webserver-session-arg-active-user
- make the active user get set on initializing the Application object if a --session flag is given
diff --git a/internal/webserver/handler_tweet_detail.go b/internal/webserver/handler_tweet_detail.go
index 5dc58e6..92e8f77 100644
--- a/internal/webserver/handler_tweet_detail.go
+++ b/internal/webserver/handler_tweet_detail.go
@@ -4,8 +4,8 @@ import (
"errors"
"fmt"
"net/http"
- "path"
"strconv"
+ "strings"
"gitlab.com/offline-twitter/twitter_offline_engine/pkg/persistence"
"gitlab.com/offline-twitter/twitter_offline_engine/pkg/scraper"
@@ -39,10 +39,11 @@ func (t TweetDetailData) FocusedTweetID() scraper.TweetID {
func (app *Application) TweetDetail(w http.ResponseWriter, r *http.Request) {
app.traceLog.Printf("'TweetDetail' handler (path: %q)", r.URL.Path)
- _, tail := path.Split(r.URL.Path)
- val, err := strconv.Atoi(tail)
+
+ parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
+ val, err := strconv.Atoi(parts[1])
if err != nil {
- app.error_400_with_message(w, fmt.Sprintf("Invalid tweet ID: %q", tail))
+ app.error_400_with_message(w, fmt.Sprintf("Invalid tweet ID: %q", parts[1]))
return
}
tweet_id := scraper.TweetID(val)
@@ -74,7 +75,7 @@ func (app *Application) TweetDetail(w http.ResponseWriter, r *http.Request) {
} else {
panic(err)
}
- } else if !tweet.IsConversationScraped {
+ } else if !tweet.IsConversationScraped || (len(parts) > 2 && parts[2] == "scrape") {
try_scrape_tweet() // If it fails, we can still render it (not 404)
}
diff --git a/internal/webserver/static/styles.css b/internal/webserver/static/styles.css
index 2e811aa..05f77ee 100644
--- a/internal/webserver/static/styles.css
+++ b/internal/webserver/static/styles.css
@@ -171,6 +171,7 @@ a.entity {
}
img.embedded-link-preview {
border-radius: 1em;
+ max-width: 100%;
}
.embedded-link-description {
color: var(--color-twitter-text-gray);
@@ -312,6 +313,7 @@ ul.quick-links {
.quick-link span {
padding: 0 0.3em;
+ white-space: nowrap;
}
.followers-count, .following-count {
@@ -534,3 +536,21 @@ ul.space-participants-list li {
.space-participants-list .author-info .profile-image {
font-size: 0.8em;
}
+
+.dropdown {
+ position: relative;
+}
+ul.dropdown-items {
+ list-style: none;
+ position: absolute;
+ top: 2em;
+ width: fit-content;
+ padding: 0.3em;
+ background-color: var(--color-twitter-off-white);
+ outline: 1px solid var(--color-outline-gray);
+ border-radius: 0.3em;
+ visibility: hidden;
+}
+.dropdown-button:focus + .dropdown-items, .dropdown-items:hover {
+ visibility: visible;
+}
diff --git a/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl b/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl
index 0be4528..12e3775 100644
--- a/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl
+++ b/internal/webserver/tpl/tweet_page_includes/single_tweet.tpl
@@ -69,7 +69,7 @@
class="embedded-link rounded-gray-outline unstyled-link"
target="_blank"
href="{{.Text}}"
- style="width: {{if (ne .ThumbnailWidth 0)}}{{.ThumbnailWidth}}px {{else}}fit-content {{end}}">
+ style="max-width: {{if (ne .ThumbnailWidth 0)}}{{.ThumbnailWidth}}px {{else}}fit-content {{end}}">