fix(reader): URL-encode file paths and JSON-encode init config to fix comics/manga loading

The reader failed to load comics and manga (and any file with special
characters in its path) for two reasons:

1. FileURL was built with raw fmt.Sprintf instead of ResolveMediaURL,
   so characters like '#' in paths (e.g. 'Annual #2') were interpreted
   as URL fragments, truncating the path and causing 404s.

2. The Alpine x-init expression used raw string interpolation for config
   values, so apostrophes in paths (e.g. "I'll Use My Appraisal Skill")
   broke JavaScript parsing with 'Unexpected identifier'.

Fix by using utils.ResolveMediaURL for proper URL path encoding and
json.Marshal for the initReader config to safely escape all special
characters.
This commit is contained in:
2026-04-23 20:39:36 -04:00
parent 70d8ffd528
commit 35c8ffe33e
3 changed files with 48 additions and 16 deletions
+17 -2
View File
@@ -1,6 +1,21 @@
package templates
import "fmt"
import (
"encoding/json"
"fmt"
)
func readerInitExpr(metadata ReaderMetadata) string {
config := map[string]string{
"mediaItemId": metadata.MediaItemID,
"fileUrl": metadata.FileURL,
"formatGroup": metadata.FormatGroup,
"readingDirection": metadata.ReadingDirection,
"mangaType": metadata.MangaType,
}
jsonBytes, _ := json.Marshal(config)
return fmt.Sprintf("initReader(%s)", string(jsonBytes))
}
templ Reader(user User, metadata ReaderMetadata, progress ReadingProgress, bookmarks []Bookmark) {
<!DOCTYPE html>
@@ -17,7 +32,7 @@ templ Reader(user User, metadata ReaderMetadata, progress ReadingProgress, bookm
</head>
<body
x-data="readerShell"
x-init={ fmt.Sprintf(`initReader({mediaItemId:'%s',fileUrl:'%s',formatGroup:'%s',readingDirection:'%s',mangaType:'%s'})`, metadata.MediaItemID, metadata.FileURL, metadata.FormatGroup, metadata.ReadingDirection, metadata.MangaType) }
x-init={ readerInitExpr(metadata) }
class="theme-tokyo-night h-screen overflow-hidden"
>
@ReaderChrome(user, metadata, progress)