feat: support direct annotation links

This commit is contained in:
Solomon Victorino 2024-04-06 00:14:51 -06:00
parent a614f9b2a0
commit 42e0625695
5 changed files with 36 additions and 8 deletions

View File

@ -18,7 +18,7 @@ import (
func annotations(l *logrus.Logger) http.HandlerFunc { func annotations(l *logrus.Logger) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] id := mux.Vars(r)["annotation-id"]
if a, err := getCache[data.Annotation]("annotation:" + id); err == nil { if a, err := getCache[data.Annotation]("annotation:" + id); err == nil {
encoder := json.NewEncoder(w) encoder := json.NewEncoder(w)

View File

@ -16,13 +16,15 @@ func New(logger *logrus.Logger) *mux.Router {
r.Use(mustHeaders) r.Use(mustHeaders)
r.Handle("/", templ.Handler(views.HomePage())) r.Handle("/", templ.Handler(views.HomePage()))
r.HandleFunc("/{id}-lyrics", lyrics(logger)).Methods("GET")
r.HandleFunc("/albums/{artist}/{albumName}", album(logger)).Methods("GET") r.HandleFunc("/albums/{artist}/{albumName}", album(logger)).Methods("GET")
r.HandleFunc("/images/{filename}.{ext}", imageProxy(logger)).Methods("GET") r.HandleFunc("/images/{filename}.{ext}", imageProxy(logger)).Methods("GET")
r.HandleFunc("/search", search(logger)).Methods("GET") r.HandleFunc("/search", search(logger)).Methods("GET")
r.HandleFunc("/{id}/{artist-song}/{verse}/annotations", annotations(logger)).Methods("GET") r.HandleFunc("/{annotation-id}/{artist-song}/{verse}/annotations", annotations(logger)).Methods("GET")
r.HandleFunc("/instances.json", instances(logger)).Methods("GET") r.HandleFunc("/instances.json", instances(logger)).Methods("GET")
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
r.PathPrefix("/{annotation-id}/{artist-song}-lyrics").HandlerFunc(lyrics(logger)).Methods("GET")
r.PathPrefix("/{annotation-id}/{artist-song}").HandlerFunc(lyrics(logger)).Methods("GET")
r.PathPrefix("/{annotation-id}").HandlerFunc(lyrics(logger)).Methods("GET")
r.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { r.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
views.ErrorPage(404, "page not found").Render(context.Background(), w) views.ErrorPage(404, "page not found").Render(context.Background(), w)

View File

@ -14,14 +14,20 @@ import (
func lyrics(l *logrus.Logger) http.HandlerFunc { func lyrics(l *logrus.Logger) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"] // prefer artist-song over annotation-id for cache key when available
id := mux.Vars(r)["artist-song"]
if id == "" {
id = mux.Vars(r)["annotation-id"]
} else {
id = id + "-lyrics"
}
if s, err := getCache[data.Song](id); err == nil { if s, err := getCache[data.Song](id); err == nil {
views.LyricsPage(s).Render(context.Background(), w) views.LyricsPage(s).Render(context.Background(), w)
return return
} }
url := fmt.Sprintf("https://genius.com/%s-lyrics", id) url := fmt.Sprintf("https://genius.com/%s", id)
resp, err := sendRequest(url) resp, err := sendRequest(url)
if err != nil { if err != nil {
l.Errorln(err) l.Errorln(err)

View File

@ -10,7 +10,18 @@ import (
) )
func TestLyrics(t *testing.T) { func TestLyrics(t *testing.T) {
url := "/The-silver-seas-catch-yer-own-train-lyrics" urls := []string{"/The-silver-seas-catch-yer-own-train-lyrics",
"/1784308/The-silver-seas-catch-yer-own-train",
"/1784308/The-silver-seas-catch-yer-own-train-lyrics",
"/1784308/The-silver-seas-catch-yer-own-train/Baby-you-and-i-are-not-the-same-you-say-you-like-sun-i-like-the-rain",
"/1784308/The-silver-seas-catch-yer-own-train-lyrics/Baby-you-and-i-are-not-the-same-you-say-you-like-sun-i-like-the-rain",
"/1784308"}
for _, url := range urls {
t.Run(url, func(t *testing.T) { testLyrics(t, url) })
}
}
func testLyrics(t *testing.T, url string) {
title := "The Silver Seas" title := "The Silver Seas"
artist := "Catch Yer Own Train" artist := "Catch Yer Own Train"

View File

@ -8,8 +8,17 @@ function showAbout() {
fullAbout && [fullAbout, summary].forEach(item => item.onclick = showAbout) fullAbout && [fullAbout, summary].forEach(item => item.onclick = showAbout)
document.querySelectorAll("#lyrics a").forEach(item => { window.addEventListener("load", () => {
document.querySelectorAll("#lyrics a").forEach(item => {
item.addEventListener("click", getAnnotation) item.addEventListener("click", getAnnotation)
})
const linkedAnnotationId = window.location.pathname.match(new RegExp("/(\\d+)"))?.[1]
if (linkedAnnotationId) {
const target = document.querySelector(`a[href^="/${linkedAnnotationId}"][class^="ReferentFragmentdesktop__ClickTarget"] > span`)
target?.click()
target?.scrollIntoView()
}
}) })
function getAnnotation(e) { function getAnnotation(e) {