feat(cards): YouTube oEmbed; UI: inline actions in header, 🌝/🌚 summarize toggle, header collapse hides all
This commit is contained in:
parent
2680abcf1f
commit
29d94c13d5
2 changed files with 35 additions and 3 deletions
|
|
@ -270,6 +270,38 @@ func (s *Server) handleLinkCard(w http.ResponseWriter, r *http.Request) {
|
|||
// fallthrough to generic fetch if oEmbed fails
|
||||
}
|
||||
|
||||
// Special handling for YouTube via oEmbed
|
||||
if host == "www.youtube.com" || host == "youtube.com" || host == "m.youtube.com" || host == "youtu.be" {
|
||||
watchURL := raw
|
||||
if host == "youtu.be" {
|
||||
// Convert youtu.be/ID to watch?v=ID
|
||||
id := strings.TrimPrefix(u.Path, "/")
|
||||
watchURL = "https://www.youtube.com/watch?v=" + id
|
||||
}
|
||||
oembed := "https://www.youtube.com/oembed?format=json&url=" + url.QueryEscape(watchURL)
|
||||
client := &http.Client{Timeout: 8 * time.Second}
|
||||
reqY, _ := http.NewRequestWithContext(r.Context(), http.MethodGet, oembed, nil)
|
||||
respY, errY := client.Do(reqY)
|
||||
if errY == nil && respY.StatusCode >= 200 && respY.StatusCode < 300 {
|
||||
defer respY.Body.Close()
|
||||
var o struct{
|
||||
Title string `json:"title"`
|
||||
Author string `json:"author_name"`
|
||||
Thumb string `json:"thumbnail_url"`
|
||||
HTML string `json:"html"`
|
||||
}
|
||||
if err := json.NewDecoder(respY.Body).Decode(&o); err == nil {
|
||||
card := linkCard{URL: raw, Title: o.Title, Image: o.Thumb, HTML: o.HTML}
|
||||
s.cardCache[raw] = card
|
||||
s.cardCacheExp[raw] = time.Now().Add(24 * time.Hour)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(w).Encode(card)
|
||||
return
|
||||
}
|
||||
}
|
||||
// fallthrough if oEmbed fails
|
||||
}
|
||||
|
||||
// fetch minimal HTML and extract tags using a tolerant HTML parser
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
req, _ := http.NewRequestWithContext(r.Context(), http.MethodGet, raw, nil)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue