From dbeee714577846e496eedbf4fb18cf20c66115ea Mon Sep 17 00:00:00 2001 From: syeopite Date: Fri, 28 Feb 2025 19:47:01 -0800 Subject: Apply search filters details css only to itself The CSS for the search filters details box was applied to every detail element when search.css is loaded --- assets/css/search.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'assets/css') diff --git a/assets/css/search.css b/assets/css/search.css index 7036fd28..833ec7e9 100644 --- a/assets/css/search.css +++ b/assets/css/search.css @@ -1,4 +1,4 @@ -summary { +#filters-collapse summary { /* This should hide the marker */ display: block; @@ -8,10 +8,10 @@ summary { cursor: pointer; } -summary::-webkit-details-marker, -summary::marker { display: none; } +#filters-collapse summary::-webkit-details-marker, +#filters-collapse summary::marker { display: none; } -summary:before { +#filters-collapse summary:before { border-radius: 5px; content: "[ + ]"; margin: -2px 10px 0 10px; @@ -20,7 +20,7 @@ summary:before { width: 40px; } -details[open] > summary:before { content: "[ − ]"; } +#filters-collapse details[open] > summary:before { content: "[ − ]"; } #filters-box { -- cgit v1.2.3 From 9de69c0052b004c22a1d83f10193e13d1f3d5c58 Mon Sep 17 00:00:00 2001 From: syeopite Date: Fri, 28 Feb 2025 20:42:07 -0800 Subject: Improve design of placeholder item Also makes it show the error backtrace --- assets/css/default.css | 47 +++++++++++++++++++++++++++++++++ locales/en-US.json | 4 ++- src/invidious/helpers/errors.cr | 29 +++++++++++++------- src/invidious/views/components/item.ecr | 12 +++++++-- 4 files changed, 79 insertions(+), 13 deletions(-) (limited to 'assets/css') diff --git a/assets/css/default.css b/assets/css/default.css index 2cedcf0c..8de224eb 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -816,3 +816,50 @@ h1, h2, h3, h4, h5, p, #download_widget { width: 100%; } + +.error-card { + display: flex; + flex-direction: column; + align-items: center; + padding: 25px; + margin-bottom: 1em; + border-radius: 10px; + border: 1px solid black; + box-sizing: border-box; + height: 100%; +} + +.error-card > .explanation { + display: grid; + grid-template-columns: max-content 1fr; + grid-template-rows: 1fr max-content; + column-gap: 10px; + row-gap: 4px; +} + +.error-card > .explanation > i { + grid-area: 1 / 1 / 2 / 2; +} + +.error-card > .explanation > h4 { + grid-area: 1 / 2 / 2 / 3; + margin: 0; +} + +.error-card > .explanation > p { + grid-area: 2 / 2 / 3 / 3; + margin: 0; +} + +.error-card details { + margin-top: 10px; + width: 100%; +} + +.error-card summary { + width: 100%; +} + +.error-card pre { + height: 300px; +} \ No newline at end of file diff --git a/locales/en-US.json b/locales/en-US.json index 4f2c2770..c9a48972 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -501,5 +501,7 @@ "toggle_theme": "Toggle Theme", "carousel_slide": "Slide {{current}} of {{total}}", "carousel_skip": "Skip the Carousel", - "carousel_go_to": "Go to slide `x`" + "carousel_go_to": "Go to slide `x`", + "timeline_parse_error_placeholder_heading": "Unable to parse item", + "timeline_parse_error_placeholder_message": "Invidious encountered an error while trying to parse this item. For more information see below:" } diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr index 900cb0c6..399324cd 100644 --- a/src/invidious/helpers/errors.cr +++ b/src/invidious/helpers/errors.cr @@ -18,16 +18,7 @@ def github_details(summary : String, content : String) return HTML.escape(details) end -def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exception : Exception) - if exception.is_a?(InfoException) - return error_template_helper(env, status_code, exception.message || "") - end - - locale = env.get("preferences").as(Preferences).locale - - env.response.content_type = "text/html" - env.response.status_code = status_code - +def get_issue_template(env : HTTP::Server::Context, exception : Exception) : Tuple(String, String) issue_title = "#{exception.message} (#{exception.class})" issue_template = <<-TEXT @@ -40,6 +31,24 @@ def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exce issue_template += github_details("Backtrace", exception.inspect_with_backtrace) + return {issue_title, issue_template} +end + +def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exception : Exception) + if exception.is_a?(InfoException) + return error_template_helper(env, status_code, exception.message || "") + end + + locale = env.get("preferences").as(Preferences).locale + + env.response.content_type = "text/html" + env.response.status_code = status_code + + # Unpacking into issue_title, issue_template directly causes a compiler error + # I have no idea why. + issue_template_components = get_issue_template(env, exception) + issue_title, issue_template = issue_template_components + # URLs for the error message below url_faq = "https://github.com/iv-org/documentation/blob/master/docs/faq.md" url_search_issues = "https://github.com/iv-org/invidious/issues" diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 79cc4725..348ea127 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -98,8 +98,16 @@ <% when Category %> <% when ProblematicTimelineItem %> -
-

Unable to parse this item

+
+
+ +

<%=translate(locale, "timeline_parse_error_placeholder_heading")%>

+

<%=translate(locale, "timeline_parse_error_placeholder_message")%>

+
+
+ Show technical details +
<%=get_issue_template(env, item.parse_exception)[1]%>
+
<% else %> <%- -- cgit v1.2.3 From 180d77276b92f8a54946dd1c4252e07fea12dc47 Mon Sep 17 00:00:00 2001 From: syeopite Date: Fri, 28 Feb 2025 20:58:16 -0800 Subject: Emphasise error card icon --- assets/css/default.css | 3 +++ 1 file changed, 3 insertions(+) (limited to 'assets/css') diff --git a/assets/css/default.css b/assets/css/default.css index 8de224eb..15eee34f 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -833,11 +833,14 @@ h1, h2, h3, h4, h5, p, display: grid; grid-template-columns: max-content 1fr; grid-template-rows: 1fr max-content; + align-items: center; column-gap: 10px; row-gap: 4px; } .error-card > .explanation > i { + color: #f44; + font-size: 24px; grid-area: 1 / 1 / 2 / 2; } -- cgit v1.2.3 From dd16f15aaeb2b1110fa9c26f8f70c494e0e8b6e6 Mon Sep 17 00:00:00 2001 From: syeopite Date: Fri, 28 Feb 2025 21:01:26 -0800 Subject: Improve error card border color on dark theme --- assets/css/default.css | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'assets/css') diff --git a/assets/css/default.css b/assets/css/default.css index 15eee34f..9d2ab34b 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -550,6 +550,10 @@ span > select { color: #565d64; } +.light-theme .error-card { + border: 1px solid black; +} + @media (prefers-color-scheme: light) { .no-theme a:hover, .no-theme a:active, @@ -596,6 +600,10 @@ span > select { .light-theme .pure-menu-heading { color: #565d64; } + + .no-theme .error-card { + border: 1px solid black; + } } @@ -658,6 +666,10 @@ body.dark-theme { color: inherit; } +.dark-theme .error-card { + border: 1px solid #5e5e5e; +} + @media (prefers-color-scheme: dark) { .no-theme a:hover, .no-theme a:active, @@ -719,6 +731,10 @@ body.dark-theme { .no-theme footer a { color: #adadad !important; } + + .no-theme .error-card { + border: 1px solid #5e5e5e; + } } @@ -824,7 +840,6 @@ h1, h2, h3, h4, h5, p, padding: 25px; margin-bottom: 1em; border-radius: 10px; - border: 1px solid black; box-sizing: border-box; height: 100%; } -- cgit v1.2.3 From 6c063436d4259d62ed6794e99298348b0be74b61 Mon Sep 17 00:00:00 2001 From: syeopite Date: Sat, 5 Apr 2025 12:23:42 -0700 Subject: Fix issues raised by code review Remove explicit `self.` from #process of parsers Remove explicit return tuple in get_issue_template Fix formatting Move inline issue template style to stylesheet Use @id in ProblematicTimelineItem xml repr Fix naming --- assets/css/default.css | 5 +++++ src/invidious/helpers/errors.cr | 4 ++-- src/invidious/helpers/serialized_yt_data.cr | 2 +- src/invidious/playlists.cr | 4 +--- src/invidious/routes/embed.cr | 8 ++++---- src/invidious/views/components/item.ecr | 2 +- src/invidious/yt_backend/extractors.cr | 22 +++++++++++----------- 7 files changed, 25 insertions(+), 22 deletions(-) (limited to 'assets/css') diff --git a/assets/css/default.css b/assets/css/default.css index 9d2ab34b..01d4b736 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -880,4 +880,9 @@ h1, h2, h3, h4, h5, p, .error-card pre { height: 300px; +} + +.error-issue-template { + padding: 20px; + background: rgba(0, 0, 0, 0.12345); } \ No newline at end of file diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr index 399324cd..e2c4b650 100644 --- a/src/invidious/helpers/errors.cr +++ b/src/invidious/helpers/errors.cr @@ -31,7 +31,7 @@ def get_issue_template(env : HTTP::Server::Context, exception : Exception) : Tup issue_template += github_details("Backtrace", exception.inspect_with_backtrace) - return {issue_title, issue_template} + return issue_title, issue_template end def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exception : Exception) @@ -78,7 +78,7 @@ def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exce

#{translate(locale, "crash_page_report_issue", url_new_issue)}

-
#{issue_template}
+
#{issue_template}
END_HTML diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index a6501e41..2796a8dc 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -320,7 +320,7 @@ struct ProblematicTimelineItem def to_xml(env, locale, xml : XML::Builder) xml.element("entry") do - xml.element("id") { xml.text "iv-err-#{Random.new.base64(8)}" } + xml.element("id") { xml.text "iv-err-#{@id}" } xml.element("title") { xml.text "Parse Error: This item has failed to parse" } xml.element("updated") { xml.text Time.utc.to_rfc3339 } diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr index c762b64b..7c584d15 100644 --- a/src/invidious/playlists.cr +++ b/src/invidious/playlists.cr @@ -501,9 +501,7 @@ def extract_playlist_videos(initial_data : Hash(String, JSON::Any)) }) end rescue ex - videos << ProblematicTimelineItem.new( - parse_exception: ex - ) + videos << ProblematicTimelineItem.new(parse_exception: ex) end return videos diff --git a/src/invidious/routes/embed.cr b/src/invidious/routes/embed.cr index b7ae4e0e..930e4915 100644 --- a/src/invidious/routes/embed.cr +++ b/src/invidious/routes/embed.cr @@ -13,14 +13,14 @@ module Invidious::Routes::Embed raise NotFoundException.new(translate(locale, "error_video_not_in_playlist", url)) end - get_first_video = videos[0].as(PlaylistVideo) + first_playlist_video = videos[0].as(PlaylistVideo) rescue ex : NotFoundException return error_template(404, ex) rescue ex return error_template(500, ex) end - url = "/embed/#{get_first_video}?#{env.params.query}" + url = "/embed/#{first_playlist_video}?#{env.params.query}" if env.params.query.size > 0 url += "?#{env.params.query}" @@ -75,14 +75,14 @@ module Invidious::Routes::Embed raise NotFoundException.new(translate(locale, "error_video_not_in_playlist", url)) end - get_first_video = videos[0].as(PlaylistVideo) + first_playlist_video = videos[0].as(PlaylistVideo) rescue ex : NotFoundException return error_template(404, ex) rescue ex return error_template(500, ex) end - url = "/embed/#{get_first_video.id}" + url = "/embed/#{first_playlist_video.id}" elsif video_series url = "/embed/#{video_series.shift}" env.params.query["playlist"] = video_series.join(",") diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 279a74b2..a24423df 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -106,7 +106,7 @@
<%=translate(locale, "timeline_parse_error_show_technical_details")%> -
<%=get_issue_template(env, item.parse_exception)[1]%>
+
<%=get_issue_template(env, item.parse_exception)[1]%>
<% else %> diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index 321957f1..df2de81d 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -62,7 +62,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = (item["videoRenderer"]? || item["gridVideoRenderer"]?) return self.parse(item_contents, author_fallback) end @@ -190,7 +190,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = (item["channelRenderer"]? || item["gridChannelRenderer"]?) return self.parse(item_contents, author_fallback) end @@ -253,7 +253,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["hashtagTileRenderer"]? return self.parse(item_contents) end @@ -306,7 +306,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["gridPlaylistRenderer"]? return self.parse(item_contents, author_fallback) end @@ -350,7 +350,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["playlistRenderer"]? return self.parse(item_contents, author_fallback) end @@ -413,7 +413,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["shelfRenderer"]? return self.parse(item_contents, author_fallback) end @@ -481,7 +481,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item.dig?("itemSectionRenderer", "contents", 0) return self.parse(item_contents, author_fallback) end @@ -510,7 +510,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item.dig?("richItemRenderer", "content") return self.parse(item_contents, author_fallback) end @@ -543,7 +543,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["reelItemRenderer"]? return self.parse(item_contents, author_fallback) end @@ -640,7 +640,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["lockupViewModel"]? return self.parse(item_contents, author_fallback) end @@ -718,7 +718,7 @@ private module Parsers extend self include BaseParser - def self.process(item : JSON::Any, author_fallback : AuthorFallback) + def process(item : JSON::Any, author_fallback : AuthorFallback) if item_contents = item["shortsLockupViewModel"]? return self.parse(item_contents, author_fallback) end -- cgit v1.2.3