From 66340281e6fd8dde05b9306ccd5eaca574b99533 Mon Sep 17 00:00:00 2001 From: jonas-w Date: Thu, 3 Feb 2022 21:42:28 +0100 Subject: [PATCH 01/48] Added verification badge for channel view --- src/invidious/channels/about.cr | 13 +++++++++---- src/invidious/views/channel.ecr | 3 +++ src/invidious/views/community.ecr | 3 +++ src/invidious/views/playlists.ecr | 3 +++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index 0f3928f5d..f92681a70 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -12,7 +12,8 @@ record AboutChannel, joined : Time, is_family_friendly : Bool, allowed_regions : Array(String), - tabs : Array(String) + tabs : Array(String), + verified : Bool record AboutRelatedChannel, ucid : String, @@ -41,7 +42,7 @@ def get_about_info(ucid, locale) : AboutChannel if !initdata.has_key?("metadata") auto_generated = true end - + verified = false if auto_generated author = initdata["header"]["interactiveTabbedHeaderRenderer"]["title"]["simpleText"].as_s author_url = initdata["microformat"]["microformatDataRenderer"]["urlCanonical"].as_s @@ -62,7 +63,7 @@ def get_about_info(ucid, locale) : AboutChannel author_thumbnail = initdata["metadata"]["channelMetadataRenderer"]["avatar"]["thumbnails"][0]["url"].as_s ucid = initdata["metadata"]["channelMetadataRenderer"]["externalId"].as_s - + # Raises a KeyError on failure. banners = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["banner"]?.try &.["thumbnails"]? banner = banners.try &.[-1]?.try &.["url"].as_s? @@ -70,7 +71,10 @@ def get_about_info(ucid, locale) : AboutChannel # if banner.includes? "channels/c4/default_banner" # banner = nil # end - + badges = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["badges"]? + if !badges.nil? + verified=true + end description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" description_html = HTML.escape(description) @@ -128,6 +132,7 @@ def get_about_info(ucid, locale) : AboutChannel is_family_friendly: is_family_friendly, allowed_regions: allowed_regions, tabs: tabs, + verified: verified, ) end diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 40b553a9c..f14546a59 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -21,6 +21,9 @@
<%= author %> + <% if channel.verified %> + + <% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index f0add06bf..bb4994d29 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -20,6 +20,9 @@
<%= author %> + <% if channel.verified %> + + <% end %>
diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index 12dba088f..df9bc76df 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -20,6 +20,9 @@
<%= author %> + <% if channel.verified %> + + <% end %>
From c584e31657770e206a583972607ca0833fa42c56 Mon Sep 17 00:00:00 2001 From: jonas-w Date: Thu, 3 Feb 2022 22:14:00 +0100 Subject: [PATCH 02/48] Inlined the if statement --- src/invidious/views/channel.ecr | 5 +---- src/invidious/views/community.ecr | 5 +---- src/invidious/views/playlists.ecr | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index f14546a59..a32a2eed7 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,10 +20,7 @@
- <%= author %> - <% if channel.verified %> - - <% end %> + <%= author %><% if channel.verified %><% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index bb4994d29..7b002f042 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,10 +19,7 @@
- <%= author %> - <% if channel.verified %> - - <% end %> + <%= author %><% if channel.verified %><% end %>
diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index df9bc76df..63badf763 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,10 +19,7 @@
- <%= author %> - <% if channel.verified %> - - <% end %> + <%= author %><% if channel.verified %><% end %>
From 154bca463554c4305cf616df1e65abbf30136019 Mon Sep 17 00:00:00 2001 From: jonas-w Date: Thu, 3 Feb 2022 22:32:00 +0100 Subject: [PATCH 03/48] Added Verification Badge to Youtube Comments --- src/invidious/comments.cr | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 65f4b135b..6febbe45f 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -144,7 +144,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" author = node_comment["authorText"]?.try &.["simpleText"]? || "" - + verified = node_comment["authorCommentBadge"]? != nil + json.field "verified", verified json.field "author", author json.field "authorThumbnails" do json.array do @@ -328,7 +329,9 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) - + if child["verified"].as_bool + author_name += "" + end html << <<-END_HTML
From 1fee636afae81b45ee433b54077b41b4baf291ea Mon Sep 17 00:00:00 2001 From: jonas-w Date: Thu, 3 Feb 2022 23:18:50 +0100 Subject: [PATCH 04/48] Added verification badge to video player and error with related_videos --- src/invidious/channels/about.cr | 4 ++-- src/invidious/videos.cr | 8 +++++++- src/invidious/views/watch.ecr | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index f92681a70..6114e8af0 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -63,7 +63,7 @@ def get_about_info(ucid, locale) : AboutChannel author_thumbnail = initdata["metadata"]["channelMetadataRenderer"]["avatar"]["thumbnails"][0]["url"].as_s ucid = initdata["metadata"]["channelMetadataRenderer"]["externalId"].as_s - + # Raises a KeyError on failure. banners = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["banner"]?.try &.["thumbnails"]? banner = banners.try &.[-1]?.try &.["url"].as_s? @@ -73,7 +73,7 @@ def get_about_info(ucid, locale) : AboutChannel # end badges = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["badges"]? if !badges.nil? - verified=true + verified = true end description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" description_html = HTML.escape(description) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 446e8e033..a5ecdeeac 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -570,6 +570,10 @@ struct Video info["authorThumbnail"]?.try &.as_s || "" end + def author_verified : Bool + info["authorVerified"].as_bool + end + def sub_count_text : String info["subCountText"]?.try &.as_s || "-" end @@ -822,6 +826,7 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? .try &.dig?("runs", 0) author = channel_info.try &.dig?("text") + authorVerified = channel_info.try &.dig?("ownerBadges") != nil ucid = channel_info.try { |ci| HelperExtractors.get_browse_id(ci) } # "4,088,033 views", only available on compact renderer @@ -845,6 +850,7 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? "length_seconds" => JSON::Any.new(length || "0"), "view_count" => JSON::Any.new(view_count || "0"), "short_view_count" => JSON::Any.new(short_view_count || "0"), + "author_verified" => JSON::Any.new(authorVerified), } end @@ -1037,7 +1043,7 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") - + params["authorVerified"] = JSON::Any.new(author_info.try &.["badges"]? != nil) params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 2e0aee998..8422fce0f 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -240,7 +240,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %> + <%= author %><% if video.author_verified %><% end %>
From a2578ac6b4a3ab370e2d1d483539ce9d32c272ca Mon Sep 17 00:00:00 2001 From: jonas-w Date: Fri, 4 Feb 2022 17:55:22 +0100 Subject: [PATCH 05/48] Added Verified Badge to related videos --- src/invidious/videos.cr | 8 ++++++-- src/invidious/views/watch.ecr | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index a5ecdeeac..69468b5ec 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -826,7 +826,11 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? .try &.dig?("runs", 0) author = channel_info.try &.dig?("text") - authorVerified = channel_info.try &.dig?("ownerBadges") != nil + author_verified_badge = related["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + + author_verified = (author_verified_badge && author_verified_badge.size > 0).to_s ucid = channel_info.try { |ci| HelperExtractors.get_browse_id(ci) } # "4,088,033 views", only available on compact renderer @@ -850,7 +854,7 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? "length_seconds" => JSON::Any.new(length || "0"), "view_count" => JSON::Any.new(view_count || "0"), "short_view_count" => JSON::Any.new(short_view_count || "0"), - "author_verified" => JSON::Any.new(authorVerified), + "author_verified" => JSON::Any.new(author_verified), } end diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 8422fce0f..496ceddc3 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -314,9 +314,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %> + "><%= rv["author"]? %><% if rv["author_verified"].== "true" %><% end %> <% else %> - <%= rv["author"]? %> + <%= rv["author"]? %><% if rv["author_verified"].== "true" %><% end %> <% end %>
From 00df3e2c4034d99701091c0beefa6133f57b275c Mon Sep 17 00:00:00 2001 From: jonas-w Date: Fri, 4 Feb 2022 19:59:07 +0100 Subject: [PATCH 06/48] Refactored code and added badges to Search but many dummies because of the way components/item works --- src/invidious/channels/about.cr | 11 +++-- src/invidious/channels/channels.cr | 3 ++ src/invidious/comments.cr | 6 +-- src/invidious/helpers/serialized_yt_data.cr | 7 ++- src/invidious/mixes.cr | 4 ++ src/invidious/playlists.cr | 6 +++ src/invidious/routes/feeds.cr | 2 + src/invidious/videos.cr | 4 +- src/invidious/views/components/item.ecr | 8 ++-- src/invidious/yt_backend/extractors.cr | 48 +++++++++++++++------ 10 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index 6114e8af0..97b45df5d 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -42,7 +42,7 @@ def get_about_info(ucid, locale) : AboutChannel if !initdata.has_key?("metadata") auto_generated = true end - verified = false + if auto_generated author = initdata["header"]["interactiveTabbedHeaderRenderer"]["title"]["simpleText"].as_s author_url = initdata["microformat"]["microformatDataRenderer"]["urlCanonical"].as_s @@ -71,10 +71,9 @@ def get_about_info(ucid, locale) : AboutChannel # if banner.includes? "channels/c4/default_banner" # banner = nil # end - badges = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["badges"]? - if !badges.nil? - verified = true - end + author_verified_badges = initdata["header"]?.try &.["c4TabbedHeaderRenderer"]?.try &.["badges"]? + + author_verified = (author_verified_badges && author_verified_badges.size > 0) description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" description_html = HTML.escape(description) @@ -132,7 +131,7 @@ def get_about_info(ucid, locale) : AboutChannel is_family_friendly: is_family_friendly, allowed_regions: allowed_regions, tabs: tabs, - verified: verified, + verified: author_verified || false, ) end diff --git a/src/invidious/channels/channels.cr b/src/invidious/channels/channels.cr index e0459cc31..9e701043a 100644 --- a/src/invidious/channels/channels.cr +++ b/src/invidious/channels/channels.cr @@ -21,6 +21,7 @@ struct ChannelVideo property live_now : Bool = false property premiere_timestamp : Time? = nil property views : Int64? = nil + property author_verified : Bool #TODO currently a dummy def to_json(locale, json : JSON::Builder) json.object do @@ -218,6 +219,7 @@ def fetch_channel(ucid, pull_all_videos : Bool) live_now: live_now, premiere_timestamp: premiere_timestamp, views: views, + author_verified: false, #TODO dummy for components/item.ecr }) LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Updating or inserting video") @@ -255,6 +257,7 @@ def fetch_channel(ucid, pull_all_videos : Bool) live_now: video.live_now, premiere_timestamp: video.premiere_timestamp, views: video.views, + author_verified: false, #TODO dummy for components/item.ecr }) } videos.each do |video| diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 6febbe45f..7d52b9180 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -144,8 +144,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" author = node_comment["authorText"]?.try &.["simpleText"]? || "" - verified = node_comment["authorCommentBadge"]? != nil - json.field "verified", verified + verified = (node_comment["authorCommentBadge"]? != nil) + json.field "verified", (verified || false) json.field "author", author json.field "authorThumbnails" do json.array do @@ -329,7 +329,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) - if child["verified"].as_bool + if child["verified"]?.try &.as_bool author_name += "" end html << <<-END_HTML diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index bfbc237ce..186bca25f 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -12,6 +12,7 @@ struct SearchVideo property live_now : Bool property premium : Bool property premiere_timestamp : Time? + property author_verified : Bool def to_xml(auto_generated, query_params, xml : XML::Builder) query_params["v"] = self.id @@ -129,6 +130,7 @@ struct SearchPlaylist property video_count : Int32 property videos : Array(SearchPlaylistVideo) property thumbnail : String? + property author_verified : Bool def to_json(locale : String?, json : JSON::Builder) json.object do @@ -140,7 +142,7 @@ struct SearchPlaylist json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" - + json.field "authorVerified", self.author_verified json.field "videoCount", self.video_count json.field "videos" do json.array do @@ -182,6 +184,7 @@ struct SearchChannel property video_count : Int32 property description_html : String property auto_generated : Bool + property author_verified : Bool def to_json(locale : String?, json : JSON::Builder) json.object do @@ -189,7 +192,7 @@ struct SearchChannel json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" - + json.field "authorVerified", self.author_verified json.field "authorThumbnails" do json.array do qualities = {32, 48, 76, 100, 176, 512} diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr index 3f342b928..b578e3d97 100644 --- a/src/invidious/mixes.cr +++ b/src/invidious/mixes.cr @@ -8,6 +8,10 @@ struct MixVideo property length_seconds : Int32 property index : Int32 property rdid : String + + def author_verified + false #TODO dummy + end end struct Mix diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr index 88888a65a..a17766e3e 100644 --- a/src/invidious/playlists.cr +++ b/src/invidious/playlists.cr @@ -234,6 +234,10 @@ struct InvidiousPlaylist 0_i64 end + def author_verified + false # TODO dummy for components/item.ecr + end + def description_html HTML.escape(self.description) end @@ -252,6 +256,7 @@ def create_playlist(title, privacy, user) updated: Time.utc, privacy: privacy, index: [] of Int64, + author_verified: false, # TODO dummy for components/item.ecr }) Invidious::Database::Playlists.insert(playlist) @@ -270,6 +275,7 @@ def subscribe_playlist(user, playlist) updated: playlist.updated, privacy: PlaylistPrivacy::Private, index: [] of Int64, + author_verified: false, # TODO dummy for components/item.ecr }) Invidious::Database::Playlists.insert(playlist) diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr index f7f7b426a..6d1f098f5 100644 --- a/src/invidious/routes/feeds.cr +++ b/src/invidious/routes/feeds.cr @@ -182,6 +182,7 @@ module Invidious::Routes::Feeds paid: false, premium: false, premiere_timestamp: nil, + author_verified: false, #TODO real value }) end @@ -414,6 +415,7 @@ module Invidious::Routes::Feeds live_now: video.live_now, premiere_timestamp: video.premiere_timestamp, views: video.views, + author_verified: false, #TODO dummy for components/item.ecr }) was_insert = Invidious::Database::ChannelVideos.insert(video, with_premiere_timestamp: true) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 69468b5ec..c52cbe58e 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -1047,7 +1047,9 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") - params["authorVerified"] = JSON::Any.new(author_info.try &.["badges"]? != nil) + author_verified_badge = author_info.try &.["badges"]? + + params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge.size > 0) || false) params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 5a93d8027..db0031464 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><% end %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><% end %>

<% when MixVideo %> @@ -45,7 +45,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><% end %>

<% when PlaylistVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index 41d959620..28e920fa6 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -102,7 +102,11 @@ private module Parsers premium = false premiere_timestamp = item_contents.dig?("upcomingEventData", "startTime").try { |t| Time.unix(t.as_s.to_i64) } + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) item_contents["badges"]?.try &.as_a.each do |badge| b = badge["metadataBadgeRenderer"] case b["label"].as_s @@ -129,6 +133,7 @@ private module Parsers live_now: live_now, premium: premium, premiere_timestamp: premiere_timestamp, + author_verified: author_verified || false, }) end @@ -156,7 +161,11 @@ private module Parsers private def self.parse(item_contents, author_fallback) author = extract_text(item_contents["title"]) || author_fallback.name author_id = item_contents["channelId"]?.try &.as_s || author_fallback.id + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) author_thumbnail = HelperExtractors.get_thumbnails(item_contents) # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. # Always simpleText @@ -179,6 +188,7 @@ private module Parsers video_count: video_count, description_html: description_html, auto_generated: auto_generated, + author_verified: author_verified || false, }) end @@ -206,18 +216,23 @@ private module Parsers private def self.parse(item_contents, author_fallback) title = extract_text(item_contents["title"]) || "" plid = item_contents["playlistId"]?.try &.as_s || "" + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) video_count = HelperExtractors.get_video_count(item_contents) playlist_thumbnail = HelperExtractors.get_thumbnails(item_contents) SearchPlaylist.new({ - title: title, - id: plid, - author: author_fallback.name, - ucid: author_fallback.id, - video_count: video_count, - videos: [] of SearchPlaylistVideo, - thumbnail: playlist_thumbnail, + title: title, + id: plid, + author: author_fallback.name, + ucid: author_fallback.id, + video_count: video_count, + videos: [] of SearchPlaylistVideo, + thumbnail: playlist_thumbnail, + author_verified: author_verified || false, }) end @@ -251,7 +266,11 @@ private module Parsers author_info = item_contents.dig?("shortBylineText", "runs", 0) author = author_info.try &.["text"].as_s || author_fallback.name author_id = author_info.try { |x| HelperExtractors.get_browse_id(x) } || author_fallback.id + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) videos = item_contents["videos"]?.try &.as_a.map do |v| v = v["childVideoRenderer"] v_title = v.dig?("title", "simpleText").try &.as_s || "" @@ -267,13 +286,14 @@ private module Parsers # TODO: item_contents["publishedTimeText"]? SearchPlaylist.new({ - title: title, - id: plid, - author: author, - ucid: author_id, - video_count: video_count, - videos: videos, - thumbnail: playlist_thumbnail, + title: title, + id: plid, + author: author, + ucid: author_id, + video_count: video_count, + videos: videos, + thumbnail: playlist_thumbnail, + author_verified: author_verified || false, }) end From 9205ccc12417bd6797d3900e19f440cf3674d427 Mon Sep 17 00:00:00 2001 From: jonas-w Date: Mon, 7 Feb 2022 02:00:43 +0100 Subject: [PATCH 07/48] Removed dummy values and added checks for items.ecr --- src/invidious/channels/channels.cr | 3 --- src/invidious/mixes.cr | 5 +---- src/invidious/playlists.cr | 9 ++------- src/invidious/routes/feeds.cr | 5 ++--- src/invidious/views/components/item.ecr | 6 +++--- 5 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/invidious/channels/channels.cr b/src/invidious/channels/channels.cr index 9e701043a..e0459cc31 100644 --- a/src/invidious/channels/channels.cr +++ b/src/invidious/channels/channels.cr @@ -21,7 +21,6 @@ struct ChannelVideo property live_now : Bool = false property premiere_timestamp : Time? = nil property views : Int64? = nil - property author_verified : Bool #TODO currently a dummy def to_json(locale, json : JSON::Builder) json.object do @@ -219,7 +218,6 @@ def fetch_channel(ucid, pull_all_videos : Bool) live_now: live_now, premiere_timestamp: premiere_timestamp, views: views, - author_verified: false, #TODO dummy for components/item.ecr }) LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Updating or inserting video") @@ -257,7 +255,6 @@ def fetch_channel(ucid, pull_all_videos : Bool) live_now: video.live_now, premiere_timestamp: video.premiere_timestamp, views: video.views, - author_verified: false, #TODO dummy for components/item.ecr }) } videos.each do |video| diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr index b578e3d97..b3edea276 100644 --- a/src/invidious/mixes.cr +++ b/src/invidious/mixes.cr @@ -8,10 +8,7 @@ struct MixVideo property length_seconds : Int32 property index : Int32 property rdid : String - - def author_verified - false #TODO dummy - end + end struct Mix diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr index a17766e3e..8383b185f 100644 --- a/src/invidious/playlists.cr +++ b/src/invidious/playlists.cr @@ -234,9 +234,6 @@ struct InvidiousPlaylist 0_i64 end - def author_verified - false # TODO dummy for components/item.ecr - end def description_html HTML.escape(self.description) @@ -255,8 +252,7 @@ def create_playlist(title, privacy, user) created: Time.utc, updated: Time.utc, privacy: privacy, - index: [] of Int64, - author_verified: false, # TODO dummy for components/item.ecr + index: [] of Int64 }) Invidious::Database::Playlists.insert(playlist) @@ -274,8 +270,7 @@ def subscribe_playlist(user, playlist) created: Time.utc, updated: playlist.updated, privacy: PlaylistPrivacy::Private, - index: [] of Int64, - author_verified: false, # TODO dummy for components/item.ecr + index: [] of Int64 }) Invidious::Database::Playlists.insert(playlist) diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr index 6d1f098f5..c26e6da74 100644 --- a/src/invidious/routes/feeds.cr +++ b/src/invidious/routes/feeds.cr @@ -156,7 +156,7 @@ module Invidious::Routes::Feeds response = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}") rss = XML.parse_html(response.body) - + print(response) videos = rss.xpath_nodes("//feed/entry").map do |entry| video_id = entry.xpath_node("videoid").not_nil!.content title = entry.xpath_node("title").not_nil!.content @@ -182,7 +182,7 @@ module Invidious::Routes::Feeds paid: false, premium: false, premiere_timestamp: nil, - author_verified: false, #TODO real value + author_verified: false, # ¯\_(ツ)_/¯ }) end @@ -415,7 +415,6 @@ module Invidious::Routes::Feeds live_now: video.live_now, premiere_timestamp: video.premiere_timestamp, views: video.views, - author_verified: false, #TODO dummy for components/item.ecr }) was_insert = Invidious::Database::ChannelVideos.insert(video, with_premiere_timestamp: true) diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index db0031464..bc59233f2 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %><% end %>

<% when MixVideo %> @@ -45,7 +45,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(MixVideo) && !item.author_verified.nil? && item.author_verified %><% end %>

<% when PlaylistVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> From fe55141a7b5ba3372cc0f850fc388ef115d94a0d Mon Sep 17 00:00:00 2001 From: jonas-w Date: Mon, 7 Feb 2022 02:04:50 +0100 Subject: [PATCH 08/48] Crystal format --- src/invidious/mixes.cr | 1 - src/invidious/playlists.cr | 5 ++--- src/invidious/routes/feeds.cr | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr index b3edea276..3f342b928 100644 --- a/src/invidious/mixes.cr +++ b/src/invidious/mixes.cr @@ -8,7 +8,6 @@ struct MixVideo property length_seconds : Int32 property index : Int32 property rdid : String - end struct Mix diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr index 8383b185f..88888a65a 100644 --- a/src/invidious/playlists.cr +++ b/src/invidious/playlists.cr @@ -234,7 +234,6 @@ struct InvidiousPlaylist 0_i64 end - def description_html HTML.escape(self.description) end @@ -252,7 +251,7 @@ def create_playlist(title, privacy, user) created: Time.utc, updated: Time.utc, privacy: privacy, - index: [] of Int64 + index: [] of Int64, }) Invidious::Database::Playlists.insert(playlist) @@ -270,7 +269,7 @@ def subscribe_playlist(user, playlist) created: Time.utc, updated: playlist.updated, privacy: PlaylistPrivacy::Private, - index: [] of Int64 + index: [] of Int64, }) Invidious::Database::Playlists.insert(playlist) diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr index c26e6da74..b5b583996 100644 --- a/src/invidious/routes/feeds.cr +++ b/src/invidious/routes/feeds.cr @@ -156,7 +156,7 @@ module Invidious::Routes::Feeds response = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{channel.ucid}") rss = XML.parse_html(response.body) - print(response) + videos = rss.xpath_nodes("//feed/entry").map do |entry| video_id = entry.xpath_node("videoid").not_nil!.content title = entry.xpath_node("title").not_nil!.content @@ -182,7 +182,7 @@ module Invidious::Routes::Feeds paid: false, premium: false, premiere_timestamp: nil, - author_verified: false, # ¯\_(ツ)_/¯ + author_verified: false, # ¯\_(ツ)_/¯ }) end From f8b29674b2f09c46b74f435a485bebd04c8ce73d Mon Sep 17 00:00:00 2001 From: jonas-w Date: Mon, 7 Feb 2022 02:25:34 +0100 Subject: [PATCH 09/48] Gave them marks some space and added nil checks --- src/invidious/comments.cr | 2 +- src/invidious/views/channel.ecr | 2 +- src/invidious/views/community.ecr | 2 +- src/invidious/views/components/item.ecr | 8 ++++---- src/invidious/views/playlists.ecr | 2 +- src/invidious/views/watch.ecr | 6 +++--- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 7d52b9180..c8533c305 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -330,7 +330,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) author_name = HTML.escape(child["author"].as_s) if child["verified"]?.try &.as_bool - author_name += "" + author_name += " " end html << <<-END_HTML
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index a32a2eed7..197c636b1 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,7 +20,7 @@
- <%= author %><% if channel.verified %><% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 7b002f042..10ac5f04f 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,7 +19,7 @@
- <%= author %><% if channel.verified %><% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index bc59233f2..8b8df07f2 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><% end %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %><% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

<% when MixVideo %> @@ -45,7 +45,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(MixVideo) && !item.author_verified.nil? && item.author_verified %><% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(MixVideo) && !item.author_verified.nil? && item.author_verified %> <% end %>

<% when PlaylistVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index 63badf763..94d7a7531 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,7 +19,7 @@
- <%= author %><% if channel.verified %><% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 496ceddc3..4593affc4 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -240,7 +240,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %><% if video.author_verified %><% end %> + <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %>
@@ -314,9 +314,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %><% if rv["author_verified"].== "true" %><% end %> + "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% else %> - <%= rv["author"]? %><% if rv["author_verified"].== "true" %><% end %> + <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% end %>
From aa09bbe23dcb1cf0ec04d330722905c6bb5caf86 Mon Sep 17 00:00:00 2001 From: Jonas Wunderlich Date: Sun, 13 Mar 2022 20:16:30 +0100 Subject: [PATCH 10/48] Done some refactoring --- src/invidious/channels/about.cr | 5 +++-- src/invidious/comments.cr | 5 +++-- src/invidious/helpers/serialized_yt_data.cr | 2 ++ src/invidious/videos.cr | 8 +++++--- src/invidious/views/channel.ecr | 2 +- src/invidious/views/community.ecr | 2 +- src/invidious/views/components/item.ecr | 8 ++++---- src/invidious/views/playlists.ecr | 2 +- src/invidious/views/watch.ecr | 6 +++--- 9 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index 336132608..d48fd1fb9 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -71,9 +71,10 @@ def get_about_info(ucid, locale) : AboutChannel # if banner.includes? "channels/c4/default_banner" # banner = nil # end - author_verified_badges = initdata["header"]?.try &.["c4TabbedHeaderRenderer"]?.try &.["badges"]? + # author_verified_badges = initdata["header"]?.try &.["c4TabbedHeaderRenderer"]?.try &.["badges"]? + author_verified_badge = initdata["header"].dig?("c4TabbedHeaderRenderer", "badges", 0, "metadataBadgeRenderer", "tooltip") + author_verified = (author_verified_badge && author_verified_badge == "Verified") - author_verified = (author_verified_badges && author_verified_badges.size > 0) description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" description_html = HTML.escape(description) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 5215122ea..d94f213f4 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -145,8 +145,9 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" author = node_comment["authorText"]?.try &.["simpleText"]? || "" - verified = (node_comment["authorCommentBadge"]? != nil) - json.field "verified", (verified || false) + + json.field "verified", (node_comment["authorCommentBadge"]? != nil) + json.field "author", author json.field "authorThumbnails" do json.array do diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index 186bca25f..3918bd130 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -142,7 +142,9 @@ struct SearchPlaylist json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" + json.field "authorVerified", self.author_verified + json.field "videoCount", self.video_count json.field "videos" do json.array do diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index bbf3afa2d..66952c93a 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -594,7 +594,7 @@ struct Video end def author_verified : Bool - info["authorVerified"].as_bool + info["authorVerified"].try &.as_bool || false end def sub_count_text : String @@ -854,6 +854,7 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? end author_verified = (author_verified_badge && author_verified_badge.size > 0).to_s + ucid = channel_info.try { |ci| HelperExtractors.get_browse_id(ci) } # "4,088,033 views", only available on compact renderer @@ -1071,9 +1072,10 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") - author_verified_badge = author_info.try &.["badges"]? - params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge.size > 0) || false) + author_verified_badge = author_info.try &.dig?("badges", 0, "metadataBadgeRenderer", "tooltip") + params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge == "Verified")) + params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 197c636b1..92f81ee49 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,7 +20,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 10ac5f04f..3bc29e552 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 05478eebb..cc4ded745 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

<% when MixVideo %> @@ -45,7 +45,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(MixVideo) && !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %>

<% when PlaylistVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index 94d7a7531..c8718e7b7 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index bfd7821a1..74a5e69f3 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -206,7 +206,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %> + <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %>
@@ -280,9 +280,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% else %> - <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% end %>
From 611e7e9dd85b9c515ab990bd6a08a98757fd8319 Mon Sep 17 00:00:00 2001 From: Jonas Wunderlich Date: Sat, 26 Mar 2022 20:13:33 +0100 Subject: [PATCH 11/48] Changed icon to checkmark and for verified author to checkmark-circle --- src/invidious/comments.cr | 6 ++++-- src/invidious/views/channel.ecr | 2 +- src/invidious/views/community.ecr | 2 +- src/invidious/views/components/item.ecr | 6 +++--- src/invidious/views/playlists.ecr | 2 +- src/invidious/views/watch.ecr | 6 +++--- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index d94f213f4..54cede370 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -331,8 +331,10 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) - if child["verified"]?.try &.as_bool - author_name += " " + if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool + author_name += " " + elsif child["verified"]?.try &.as_bool + author_name += " " end html << <<-END_HTML
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 92f81ee49..d6e653b45 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,7 +20,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 3bc29e552..6b8ccd925 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index cc4ded745..86038f28d 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

<% when MixVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index c8718e7b7..87e0c75de 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 74a5e69f3..d79c6dc8d 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -206,7 +206,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %> + <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %>
@@ -280,9 +280,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% else %> - <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% end %>
From ec3e67e0d222d1f4c4bb278d7ce8ec804bebc137 Mon Sep 17 00:00:00 2001 From: Jonas Wunderlich Date: Sat, 26 Mar 2022 20:18:24 +0100 Subject: [PATCH 12/48] Wait that was too much replacing --- src/invidious/views/channel.ecr | 2 +- src/invidious/views/community.ecr | 2 +- src/invidious/views/components/item.ecr | 6 +++--- src/invidious/views/playlists.ecr | 2 +- src/invidious/views/watch.ecr | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index d6e653b45..92f81ee49 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,7 +20,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 6b8ccd925..3bc29e552 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 86038f28d..cc4ded745 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

<% when MixVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index 87e0c75de..c8718e7b7 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index d79c6dc8d..74a5e69f3 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -206,7 +206,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %> + <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %>
@@ -280,9 +280,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% else %> - <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% end %>
From 80d89f31feb4093ebd8d1261d4a7c622c9a20f4c Mon Sep 17 00:00:00 2001 From: DUO Labs Date: Sun, 24 Apr 2022 18:06:56 -0400 Subject: [PATCH 13/48] Widen Youtube player a bit --- assets/css/player.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/css/player.css b/assets/css/player.css index 120fd2f83..c2c24630b 100644 --- a/assets/css/player.css +++ b/assets/css/player.css @@ -70,6 +70,9 @@ margin-bottom: 2em; } +.video-js.player-style-youtube .vjs-progress-control .vjs-progress-holder, .video-js.player-style-youtube .vjs-progress-control {height: 5px; +margin-bottom: 24px;} + ul.vjs-menu-content::-webkit-scrollbar { display: none; } From a7cf1f6ccaf286ba039b04c74e3ad052fd744ea7 Mon Sep 17 00:00:00 2001 From: DUO Labs Date: Sun, 24 Apr 2022 19:06:28 -0400 Subject: [PATCH 14/48] Update player.css Fixed "floating" seek bar --- assets/css/player.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/css/player.css b/assets/css/player.css index c2c24630b..061dbd58e 100644 --- a/assets/css/player.css +++ b/assets/css/player.css @@ -71,7 +71,7 @@ } .video-js.player-style-youtube .vjs-progress-control .vjs-progress-holder, .video-js.player-style-youtube .vjs-progress-control {height: 5px; -margin-bottom: 24px;} +margin-bottom: 20px;} ul.vjs-menu-content::-webkit-scrollbar { display: none; From ab62fa1c4f43154d5513e2bda5a83268959f08c6 Mon Sep 17 00:00:00 2001 From: DUO Labs Date: Sun, 24 Apr 2022 19:51:29 -0400 Subject: [PATCH 15/48] Lower margin-bottom some more --- assets/css/player.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/css/player.css b/assets/css/player.css index 061dbd58e..304375b54 100644 --- a/assets/css/player.css +++ b/assets/css/player.css @@ -71,7 +71,7 @@ } .video-js.player-style-youtube .vjs-progress-control .vjs-progress-holder, .video-js.player-style-youtube .vjs-progress-control {height: 5px; -margin-bottom: 20px;} +margin-bottom: 10px;} ul.vjs-menu-content::-webkit-scrollbar { display: none; From eb7e48b05999b29670a2de80e6f53bd8b4fd8d15 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 11:38:24 +0300 Subject: [PATCH 16/48] use strict --- assets/js/community.js | 1 + assets/js/embed.js | 1 + assets/js/notifications.js | 1 + assets/js/player.js | 1 + assets/js/playlist_widget.js | 1 + assets/js/subscribe_widget.js | 1 + assets/js/themes.js | 1 + assets/js/watch.js | 1 + assets/js/watched_widget.js | 1 + 9 files changed, 9 insertions(+) diff --git a/assets/js/community.js b/assets/js/community.js index 4077f1cd5..2e7a1f6da 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -1,3 +1,4 @@ +'use strict'; var community_data = JSON.parse(document.getElementById('community_data').innerHTML); String.prototype.supplant = function (o) { diff --git a/assets/js/embed.js b/assets/js/embed.js index 9d0be0ea9..7d66c8c4d 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -1,3 +1,4 @@ +'use strict'; var video_data = JSON.parse(document.getElementById('video_data').innerHTML); function get_playlist(plid, retries) { diff --git a/assets/js/notifications.js b/assets/js/notifications.js index 3d1ec1ed5..68ea1e156 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -1,3 +1,4 @@ +'use strict'; var notification_data = JSON.parse(document.getElementById('notification_data').innerHTML); var notifications, delivered; diff --git a/assets/js/player.js b/assets/js/player.js index f5bec6510..496cdfd01 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -1,3 +1,4 @@ +'use strict'; var player_data = JSON.parse(document.getElementById('player_data').innerHTML); var video_data = JSON.parse(document.getElementById('video_data').innerHTML); diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index 0ec27859a..971f3806f 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -1,3 +1,4 @@ +'use strict'; var playlist_data = JSON.parse(document.getElementById('playlist_data').innerHTML); function add_playlist_video(target) { diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index 216c36fe4..bb6c75566 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -1,3 +1,4 @@ +'use strict'; var subscribe_data = JSON.parse(document.getElementById('subscribe_data').innerHTML); var subscribe_button = document.getElementById('subscribe'); diff --git a/assets/js/themes.js b/assets/js/themes.js index 0214a7f06..2f4680c72 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -1,3 +1,4 @@ +'use strict'; var toggle_theme = document.getElementById('toggle_theme'); toggle_theme.href = 'javascript:void(0);'; diff --git a/assets/js/watch.js b/assets/js/watch.js index 1579abf4e..43df05615 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -1,3 +1,4 @@ +'use strict'; var video_data = JSON.parse(document.getElementById('video_data').innerHTML); String.prototype.supplant = function (o) { diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index ba741974e..372cbbaba 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -1,3 +1,4 @@ +'use strict'; var watched_data = JSON.parse(document.getElementById('watched_data').innerHTML); function mark_watched(target) { From c72d3c4a0ea9329fa455d5c066aff598c307d04d Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 12:05:19 +0300 Subject: [PATCH 17/48] semicolons --- assets/js/community.js | 6 ++--- assets/js/embed.js | 10 ++++----- assets/js/handlers.js | 6 ++--- assets/js/notifications.js | 16 ++++++------- assets/js/player.js | 42 +++++++++++++++++------------------ assets/js/playlist_widget.js | 6 ++--- assets/js/subscribe_widget.js | 16 ++++++------- assets/js/watch.js | 38 +++++++++++++++---------------- assets/js/watched_widget.js | 6 ++--- 9 files changed, 73 insertions(+), 73 deletions(-) diff --git a/assets/js/community.js b/assets/js/community.js index 2e7a1f6da..5bc1ee2e5 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -6,7 +6,7 @@ String.prototype.supplant = function (o) { var r = o[b]; return typeof r === 'string' || typeof r === 'number' ? r : a; }); -} +}; function hide_youtube_replies(event) { var target = event.target; @@ -93,12 +93,12 @@ function get_youtube_replies(target, load_more) { body.innerHTML = fallback; } } - } + }; xhr.ontimeout = function () { console.log('Pulling comments failed.'); body.innerHTML = fallback; - } + }; xhr.send(); } diff --git a/assets/js/embed.js b/assets/js/embed.js index 7d66c8c4d..11d940600 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -58,17 +58,17 @@ function get_playlist(plid, retries) { } } } - } + }; xhr.onerror = function () { console.log('Pulling playlist failed... ' + retries + '/5'); - setTimeout(function () { get_playlist(plid, retries - 1) }, 1000); - } + setTimeout(function () { get_playlist(plid, retries - 1); }, 1000); + }; xhr.ontimeout = function () { console.log('Pulling playlist failed... ' + retries + '/5'); get_playlist(plid, retries - 1); - } + }; xhr.send(); } @@ -97,7 +97,7 @@ window.addEventListener('load', function (e) { } if (video_data.video_series.length !== 0) { - url.searchParams.set('playlist', video_data.video_series.join(',')) + url.searchParams.set('playlist', video_data.video_series.join(',')); } location.assign(url.pathname + url.search); diff --git a/assets/js/handlers.js b/assets/js/handlers.js index 021759577..84e1d7c29 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -76,7 +76,7 @@ }); n2a(document.querySelectorAll('[data-onrange="update_volume_value"]')).forEach(function (e) { - var cb = function () { update_volume_value(e); } + var cb = function () { update_volume_value(e); }; e.oninput = cb; e.onchange = cb; }); @@ -108,7 +108,7 @@ row.style.display = ''; } } - } + }; var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value; xhr.send('csrf_token=' + csrf_token); @@ -137,7 +137,7 @@ row.style.display = ''; } } - } + }; var csrf_token = target.parentNode.querySelector('input[name="csrf_token"]').value; xhr.send('csrf_token=' + csrf_token); diff --git a/assets/js/notifications.js b/assets/js/notifications.js index 68ea1e156..9c77895b8 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -22,17 +22,17 @@ function get_subscriptions(callback, retries) { callback(subscriptions); } } - } + }; xhr.onerror = function () { console.log('Pulling subscriptions failed... ' + retries + '/5'); - setTimeout(function () { get_subscriptions(callback, retries - 1) }, 1000); - } + setTimeout(function () { get_subscriptions(callback, retries - 1); }, 1000); + }; xhr.ontimeout = function () { console.log('Pulling subscriptions failed... ' + retries + '/5'); get_subscriptions(callback, retries - 1); - } + }; xhr.send(); } @@ -41,7 +41,7 @@ function create_notification_stream(subscriptions) { notifications = new SSE( '/api/v1/auth/notifications?fields=videoId,title,author,authorId,publishedText,published,authorThumbnails,liveNow', { withCredentials: true, - payload: 'topics=' + subscriptions.map(function (subscription) { return subscription.authorId }).join(','), + payload: 'topics=' + subscriptions.map(function (subscription) { return subscription.authorId; }).join(','), headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); delivered = []; @@ -68,7 +68,7 @@ function create_notification_stream(subscriptions) { system_notification.onclick = function (event) { window.open('/watch?v=' + event.currentTarget.tag, '_blank'); - } + }; } delivered.push(notification.videoId); @@ -83,7 +83,7 @@ function create_notification_stream(subscriptions) { ''; } } - } + }; notifications.addEventListener('error', handle_notification_error); notifications.stream(); @@ -92,7 +92,7 @@ function create_notification_stream(subscriptions) { function handle_notification_error(event) { console.log('Something went wrong with notifications, trying to reconnect...'); notifications = { close: function () { } }; - setTimeout(function () { get_subscriptions(create_notification_stream) }, 1000); + setTimeout(function () { get_subscriptions(create_notification_stream); }, 1000); } window.addEventListener('load', function (e) { diff --git a/assets/js/player.js b/assets/js/player.js index 496cdfd01..a0cef29e7 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -28,7 +28,7 @@ var options = { overrideNative: true } } -} +}; if (player_data.aspect_ratio) { options.aspectRatio = player_data.aspect_ratio; @@ -147,7 +147,7 @@ if (isMobile()) { buttons = ["playToggle", "volumePanel", "captionsButton"]; - if (video_data.params.quality !== 'dash') buttons.push("qualitySelector") + if (video_data.params.quality !== 'dash') buttons.push("qualitySelector"); // Create new control bar object for operation buttons const ControlBar = videojs.getComponent("controlBar"); @@ -155,35 +155,35 @@ if (isMobile()) { children: [], playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] }); - buttons.slice(1).forEach(child => operations_bar.addChild(child)) + buttons.slice(1).forEach(child => operations_bar.addChild(child)); // Remove operation buttons from primary control bar primary_control_bar = player.getChild("controlBar"); buttons.forEach(child => primary_control_bar.removeChild(child)); operations_bar_element = operations_bar.el(); - operations_bar_element.className += " mobile-operations-bar" - player.addChild(operations_bar) + operations_bar_element.className += " mobile-operations-bar"; + player.addChild(operations_bar); // Playback menu doesn't work when it's initialized outside of the primary control bar - playback_element = document.getElementsByClassName("vjs-playback-rate")[0] - operations_bar_element.append(playback_element) + playback_element = document.getElementsByClassName("vjs-playback-rate")[0]; + operations_bar_element.append(playback_element); // The share and http source selector element can't be fetched till the players ready. player.one("playing", () => { - share_element = document.getElementsByClassName("vjs-share-control")[0] - operations_bar_element.append(share_element) + share_element = document.getElementsByClassName("vjs-share-control")[0]; + operations_bar_element.append(share_element); if (video_data.params.quality === 'dash') { - http_source_selector = document.getElementsByClassName("vjs-http-source-selector vjs-menu-button")[0] - operations_bar_element.append(http_source_selector) + http_source_selector = document.getElementsByClassName("vjs-http-source-selector vjs-menu-button")[0]; + operations_bar_element.append(http_source_selector); } - }) + }); } // Enable VR video support if (!video_data.params.listen && video_data.vr && video_data.params.vr_mode) { - player.crossOrigin("anonymous") + player.crossOrigin("anonymous"); switch (video_data.projection_type) { case "EQUIRECTANGULAR": player.vr({projection: "equirectangular"}); @@ -280,7 +280,7 @@ player.on('volumechange', function () { player.on('waiting', function () { if (player.playbackRate() > 1 && player.liveTracker.isLive() && player.liveTracker.atLiveEdge()) { - console.log('Player has caught up to source, resetting playbackRate.') + console.log('Player has caught up to source, resetting playbackRate.'); player.playbackRate(1); } }); @@ -767,12 +767,12 @@ if (window.location.pathname.startsWith("/embed/")) { // Create hyperlink for current instance redirect_element = document.createElement("a"); - redirect_element.setAttribute("href", `//${window.location.host}/watch?v=${window.location.pathname.replace("/embed/","")}`) - redirect_element.appendChild(document.createTextNode("Invidious")) + redirect_element.setAttribute("href", `//${window.location.host}/watch?v=${window.location.pathname.replace("/embed/","")}`); + redirect_element.appendChild(document.createTextNode("Invidious")); - watch_on_invidious_button.el().appendChild(redirect_element) - watch_on_invidious_button.addClass("watch-on-invidious") + watch_on_invidious_button.el().appendChild(redirect_element); + watch_on_invidious_button.addClass("watch-on-invidious"); - cb = player.getChild('ControlBar') - cb.addChild(watch_on_invidious_button) -}; + cb = player.getChild('ControlBar'); + cb.addChild(watch_on_invidious_button); +} diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index 971f3806f..0cf721a11 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -20,7 +20,7 @@ function add_playlist_video(target) { option.innerText = '✓' + option.innerText; } } - } + }; xhr.send('csrf_token=' + playlist_data.csrf_token); } @@ -44,7 +44,7 @@ function add_playlist_item(target) { tile.style.display = ''; } } - } + }; xhr.send('csrf_token=' + playlist_data.csrf_token); } @@ -68,7 +68,7 @@ function remove_playlist_item(target) { tile.style.display = ''; } } - } + }; xhr.send('csrf_token=' + playlist_data.csrf_token); } \ No newline at end of file diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index bb6c75566..bdd5d5812 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -35,17 +35,17 @@ function subscribe(retries = 5) { subscribe_button.innerHTML = fallback; } } - } + }; xhr.onerror = function () { console.log('Subscribing failed... ' + retries + '/5'); - setTimeout(function () { subscribe(retries - 1) }, 1000); - } + setTimeout(function () { subscribe(retries - 1); }, 1000); + }; xhr.ontimeout = function () { console.log('Subscribing failed... ' + retries + '/5'); subscribe(retries - 1); - } + }; xhr.send('csrf_token=' + subscribe_data.csrf_token); } @@ -75,17 +75,17 @@ function unsubscribe(retries = 5) { subscribe_button.innerHTML = fallback; } } - } + }; xhr.onerror = function () { console.log('Unsubscribing failed... ' + retries + '/5'); - setTimeout(function () { unsubscribe(retries - 1) }, 1000); - } + setTimeout(function () { unsubscribe(retries - 1); }, 1000); + }; xhr.ontimeout = function () { console.log('Unsubscribing failed... ' + retries + '/5'); unsubscribe(retries - 1); - } + }; xhr.send('csrf_token=' + subscribe_data.csrf_token); } diff --git a/assets/js/watch.js b/assets/js/watch.js index 43df05615..578d4ac0b 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -6,7 +6,7 @@ String.prototype.supplant = function (o) { var r = o[b]; return typeof r === 'string' || typeof r === 'number' ? r : a; }); -} +}; function toggle_parent(target) { body = target.parentNode.parentNode.children[1]; @@ -128,7 +128,7 @@ function get_playlist(plid, retries) { playlist.innerHTML = ' \

\ -
' +
'; if (plid.startsWith('RD')) { var plid_url = '/api/v1/mixes/' + plid + @@ -186,7 +186,7 @@ function get_playlist(plid, retries) { document.getElementById('continue').style.display = ''; } } - } + }; xhr.onerror = function () { playlist = document.getElementById('playlist'); @@ -194,8 +194,8 @@ function get_playlist(plid, retries) { '


'; console.log('Pulling playlist timed out... ' + retries + '/5'); - setTimeout(function () { get_playlist(plid, retries - 1) }, 1000); - } + setTimeout(function () { get_playlist(plid, retries - 1); }, 1000); + }; xhr.ontimeout = function () { playlist = document.getElementById('playlist'); @@ -204,7 +204,7 @@ function get_playlist(plid, retries) { console.log('Pulling playlist timed out... ' + retries + '/5'); get_playlist(plid, retries - 1); - } + }; xhr.send(); } @@ -265,23 +265,23 @@ function get_reddit_comments(retries) { } else { if (video_data.params.comments[1] === 'youtube') { console.log('Pulling comments failed... ' + retries + '/5'); - setTimeout(function () { get_youtube_comments(retries - 1) }, 1000); + setTimeout(function () { get_youtube_comments(retries - 1); }, 1000); } else { comments.innerHTML = fallback; } } } - } + }; xhr.onerror = function () { console.log('Pulling comments failed... ' + retries + '/5'); - setTimeout(function () { get_reddit_comments(retries - 1) }, 1000); - } + setTimeout(function () { get_reddit_comments(retries - 1); }, 1000); + }; xhr.ontimeout = function () { console.log('Pulling comments failed... ' + retries + '/5'); get_reddit_comments(retries - 1); - } + }; xhr.send(); } @@ -337,27 +337,27 @@ function get_youtube_comments(retries) { comments.children[0].children[1].children[0].onclick = swap_comments; } else { if (video_data.params.comments[1] === 'youtube') { - setTimeout(function () { get_youtube_comments(retries - 1) }, 1000); + setTimeout(function () { get_youtube_comments(retries - 1); }, 1000); } else { comments.innerHTML = ''; } } } - } + }; xhr.onerror = function () { comments.innerHTML = '

'; console.log('Pulling comments failed... ' + retries + '/5'); - setTimeout(function () { get_youtube_comments(retries - 1) }, 1000); - } + setTimeout(function () { get_youtube_comments(retries - 1); }, 1000); + }; xhr.ontimeout = function () { comments.innerHTML = '

'; console.log('Pulling comments failed... ' + retries + '/5'); get_youtube_comments(retries - 1); - } + }; xhr.send(); } @@ -374,7 +374,7 @@ function get_youtube_replies(target, load_more, load_replies) { '?format=html' + '&hl=' + video_data.preferences.locale + '&thin_mode=' + video_data.preferences.thin_mode + - '&continuation=' + continuation + '&continuation=' + continuation; if (load_replies) { url += '&action=action_get_comment_replies'; } @@ -413,12 +413,12 @@ function get_youtube_replies(target, load_more, load_replies) { body.innerHTML = fallback; } } - } + }; xhr.ontimeout = function () { console.log('Pulling comments failed.'); body.innerHTML = fallback; - } + }; xhr.send(); } diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 372cbbaba..22afb0542 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -19,7 +19,7 @@ function mark_watched(target) { tile.style.display = ''; } } - } + }; xhr.send('csrf_token=' + watched_data.csrf_token); } @@ -27,7 +27,7 @@ function mark_watched(target) { function mark_unwatched(target) { var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; tile.style.display = 'none'; - var count = document.getElementById('count') + var count = document.getElementById('count'); count.innerText = count.innerText - 1; var url = '/watch_ajax?action_mark_unwatched=1&redirect=false' + @@ -45,7 +45,7 @@ function mark_unwatched(target) { tile.style.display = ''; } } - } + }; xhr.send('csrf_token=' + watched_data.csrf_token); } \ No newline at end of file From 38ef0b10e79232de1c6fa2062d9983e4a944f6be Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 12:13:16 +0300 Subject: [PATCH 18/48] eqeqeq --- assets/js/community.js | 4 ++-- assets/js/embed.js | 2 +- assets/js/handlers.js | 10 +++++----- assets/js/notifications.js | 2 +- assets/js/player.js | 22 +++++++++++----------- assets/js/playlist_widget.js | 12 ++++++------ assets/js/subscribe_widget.js | 8 ++++---- assets/js/watch.js | 22 +++++++++++----------- assets/js/watched_widget.js | 8 ++++---- 9 files changed, 45 insertions(+), 45 deletions(-) diff --git a/assets/js/community.js b/assets/js/community.js index 5bc1ee2e5..eebaf5d8b 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -64,8 +64,8 @@ function get_youtube_replies(target, load_more) { xhr.open('GET', url, true); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { + if (xhr.readyState === 4) { + if (xhr.status === 200) { if (load_more) { body = body.parentNode.parentNode; body.removeChild(body.lastElementChild); diff --git a/assets/js/embed.js b/assets/js/embed.js index 11d940600..d3c530cb0 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -2,7 +2,7 @@ var video_data = JSON.parse(document.getElementById('video_data').innerHTML); function get_playlist(plid, retries) { - if (retries == undefined) retries = 5; + if (retries === undefined) retries = 5; if (retries <= 0) { console.log('Failed to pull playlist'); diff --git a/assets/js/handlers.js b/assets/js/handlers.js index 84e1d7c29..1bf11364e 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -102,8 +102,8 @@ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { count.innerText = parseInt(count.innerText) + 1; row.style.display = ''; } @@ -131,8 +131,8 @@ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { count.innerText = parseInt(count.innerText) + 1; row.style.display = ''; } @@ -159,7 +159,7 @@ } // Focus search bar on '/' - if (event.key == "/") { + if (event.key === "/") { document.getElementById('searchbox').focus(); event.preventDefault(); } diff --git a/assets/js/notifications.js b/assets/js/notifications.js index 9c77895b8..1235fb41e 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -4,7 +4,7 @@ var notification_data = JSON.parse(document.getElementById('notification_data'). var notifications, delivered; function get_subscriptions(callback, retries) { - if (retries == undefined) retries = 5; + if (retries === undefined) retries = 5; if (retries <= 0) { return; diff --git a/assets/js/player.js b/assets/js/player.js index a0cef29e7..9903e6149 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -225,7 +225,7 @@ player.playbackRate(video_data.params.speed); function getCookieValue(name) { var value = document.cookie.split(";").filter(item => item.includes(name + "=")); - return (value != null && value.length >= 1) + return (value.length >= 1) ? value[0].substring((name + "=").length, value[0].length) : null; } @@ -237,13 +237,13 @@ function getCookieValue(name) { * @param {number} newSpeed New speed defined (null if unchanged) */ function updateCookie(newVolume, newSpeed) { - var volumeValue = newVolume != null ? newVolume : video_data.params.volume; - var speedValue = newSpeed != null ? newSpeed : video_data.params.speed; + var volumeValue = newVolume !== null ? newVolume : video_data.params.volume; + var speedValue = newSpeed !== null ? newSpeed : video_data.params.speed; var cookieValue = getCookieValue('PREFS'); var cookieData; - if (cookieValue != null) { + if (cookieValue !== null) { var cookieJson = JSON.parse(decodeURIComponent(cookieValue)); cookieJson.volume = volumeValue; cookieJson.speed = speedValue; @@ -260,7 +260,7 @@ function updateCookie(newVolume, newSpeed) { var domainUsed = window.location.hostname; // Fix for a bug in FF where the leading dot in the FQDN is not ignored - if (domainUsed.charAt(0) != '.' && !ipRegex.test(domainUsed) && domainUsed != 'localhost') + if (domainUsed.charAt(0) !== '.' && !ipRegex.test(domainUsed) && domainUsed !== 'localhost') domainUsed = '.' + window.location.hostname; document.cookie = 'PREFS=' + cookieData + '; SameSite=Strict; path=/; domain=' + @@ -334,7 +334,7 @@ if (video_data.params.autoplay) { if (!video_data.params.listen && video_data.params.quality === 'dash') { player.httpSourceSelector(); - if (video_data.params.quality_dash != "auto") { + if (video_data.params.quality_dash !== "auto") { player.ready(() => { player.on("loadedmetadata", () => { const qualityLevels = Array.from(player.qualityLevels()).sort((a, b) => a.height - b.height); @@ -357,7 +357,7 @@ if (!video_data.params.listen && video_data.params.quality === 'dash') { } } for (let i = 0; i < qualityLevels.length; i++) { - qualityLevels[i].enabled = (i == targetQualityLevel); + qualityLevels[i].enabled = (i === targetQualityLevel); } }); }); @@ -703,7 +703,7 @@ window.addEventListener('keydown', e => { var volumeHover = false; var volumeSelector = pEl.querySelector('.vjs-volume-menu-button') || pEl.querySelector('.vjs-volume-panel'); - if (volumeSelector != null) { + if (volumeSelector !== null) { volumeSelector.onmouseover = function () { volumeHover = true; }; volumeSelector.onmouseout = function () { volumeHover = false; }; } @@ -723,9 +723,9 @@ window.addEventListener('keydown', e => { var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); event.preventDefault(); - if (delta == 1) { + if (delta === 1) { increase_volume(volumeStep); - } else if (delta == -1) { + } else if (delta === -1) { increase_volume(-volumeStep); } } @@ -750,7 +750,7 @@ if (player_data.preferred_caption_found) { } // Safari audio double duration fix -if (navigator.vendor == "Apple Computer, Inc." && video_data.params.listen) { +if (navigator.vendor === "Apple Computer, Inc." && video_data.params.listen) { player.on('loadedmetadata', function () { player.on('timeupdate', function () { if (player.remainingTime() < player.duration() / 2 && player.remainingTime() >= 2) { diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index 0cf721a11..c7f4805f4 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -15,8 +15,8 @@ function add_playlist_video(target) { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { + if (xhr.readyState === 4) { + if (xhr.status === 200) { option.innerText = '✓' + option.innerText; } } @@ -39,8 +39,8 @@ function add_playlist_item(target) { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { tile.style.display = ''; } } @@ -63,8 +63,8 @@ function remove_playlist_item(target) { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { tile.style.display = ''; } } diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index bdd5d5812..d44d65da6 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -29,8 +29,8 @@ function subscribe(retries = 5) { subscribe_button.innerHTML = '' + subscribe_data.unsubscribe_text + ' | ' + subscribe_data.sub_count_text + ''; xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { subscribe_button.onclick = subscribe; subscribe_button.innerHTML = fallback; } @@ -69,8 +69,8 @@ function unsubscribe(retries = 5) { subscribe_button.innerHTML = '' + subscribe_data.subscribe_text + ' | ' + subscribe_data.sub_count_text + ''; xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { subscribe_button.onclick = unsubscribe; subscribe_button.innerHTML = fallback; } diff --git a/assets/js/watch.js b/assets/js/watch.js index 578d4ac0b..ebc779057 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -117,7 +117,7 @@ function number_with_separator(val) { } function get_playlist(plid, retries) { - if (retries == undefined) retries = 5; + if (retries === undefined) retries = 5; playlist = document.getElementById('playlist'); if (retries <= 0) { @@ -147,8 +147,8 @@ function get_playlist(plid, retries) { xhr.open('GET', plid_url, true); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { + if (xhr.readyState === 4) { + if (xhr.status === 200) { playlist.innerHTML = xhr.response.playlistHtml; var nextVideo = document.getElementById(xhr.response.nextVideo); nextVideo.parentNode.parentNode.scrollTop = nextVideo.offsetTop; @@ -210,7 +210,7 @@ function get_playlist(plid, retries) { } function get_reddit_comments(retries) { - if (retries == undefined) retries = 5; + if (retries === undefined) retries = 5; comments = document.getElementById('comments'); if (retries <= 0) { @@ -232,8 +232,8 @@ function get_reddit_comments(retries) { xhr.open('GET', url, true); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { + if (xhr.readyState === 4) { + if (xhr.status === 200) { comments.innerHTML = ' \
\

\ @@ -287,7 +287,7 @@ function get_reddit_comments(retries) { } function get_youtube_comments(retries) { - if (retries == undefined) retries = 5; + if (retries === undefined) retries = 5; comments = document.getElementById('comments'); if (retries <= 0) { @@ -310,8 +310,8 @@ function get_youtube_comments(retries) { xhr.open('GET', url, true); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { + if (xhr.readyState === 4) { + if (xhr.status === 200) { comments.innerHTML = ' \
\

\ @@ -384,8 +384,8 @@ function get_youtube_replies(target, load_more, load_replies) { xhr.open('GET', url, true); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { + if (xhr.readyState === 4) { + if (xhr.status === 200) { if (load_more) { body = body.parentNode.parentNode; body.removeChild(body.lastElementChild); diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 22afb0542..bd037c2be 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -14,8 +14,8 @@ function mark_watched(target) { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { tile.style.display = ''; } } @@ -39,8 +39,8 @@ function mark_unwatched(target) { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status != 200) { + if (xhr.readyState === 4) { + if (xhr.status !== 200) { count.innerText = count.innerText - 1 + 2; tile.style.display = ''; } From 577a2356a03532517ae2f996845cc27df38fce99 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 12:36:52 +0300 Subject: [PATCH 19/48] convert arrow functions --- assets/js/handlers.js | 2 +- assets/js/player.js | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/assets/js/handlers.js b/assets/js/handlers.js index 1bf11364e..c2016bc8a 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -144,7 +144,7 @@ } // Handle keypresses - window.addEventListener('keydown', (event) => { + window.addEventListener('keydown', function (event) { // Ignore modifier keys if (event.ctrlKey || event.metaKey) return; diff --git a/assets/js/player.js b/assets/js/player.js index 9903e6149..0c5b28d47 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -117,7 +117,7 @@ var shareOptions = { } }; -const storage = (() => { +const storage = (function () { try { if (localStorage.length !== -1) return localStorage; } catch (e) { console.info('No storage available: ' + e); } @@ -155,11 +155,11 @@ if (isMobile()) { children: [], playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] }); - buttons.slice(1).forEach(child => operations_bar.addChild(child)); + buttons.slice(1).forEach(function (child) {operations_bar.addChild(child);}); // Remove operation buttons from primary control bar primary_control_bar = player.getChild("controlBar"); - buttons.forEach(child => primary_control_bar.removeChild(child)); + buttons.forEach(function (child) {primary_control_bar.removeChild(child);}); operations_bar_element = operations_bar.el(); operations_bar_element.className += " mobile-operations-bar"; @@ -170,7 +170,7 @@ if (isMobile()) { operations_bar_element.append(playback_element); // The share and http source selector element can't be fetched till the players ready. - player.one("playing", () => { + player.one("playing", function () { share_element = document.getElementsByClassName("vjs-share-control")[0]; operations_bar_element.append(share_element); @@ -223,7 +223,7 @@ player.playbackRate(video_data.params.speed); * @returns cookieValue */ function getCookieValue(name) { - var value = document.cookie.split(";").filter(item => item.includes(name + "=")); + var value = document.cookie.split(";").filter(function (item) {return item.includes(name + "=");}); return (value.length >= 1) ? value[0].substring((name + "=").length, value[0].length) @@ -297,7 +297,7 @@ if (video_data.params.save_player_pos) { if(!hasTimeParam) set_seconds_after_start(remeberedTime); - const updateTime = () => { + const updateTime = function () { const raw = player.currentTime(); const time = Math.floor(raw); @@ -317,13 +317,13 @@ if (video_data.params.autoplay) { player.ready(function () { new Promise(function (resolve, reject) { - setTimeout(() => resolve(1), 1); + setTimeout(function () {resolve(1);}, 1); }).then(function (result) { var promise = player.play(); if (promise !== undefined) { - promise.then(_ => { - }).catch(error => { + promise.then(function () { + }).catch(function (error) { bpb.show(); }); } @@ -335,9 +335,9 @@ if (!video_data.params.listen && video_data.params.quality === 'dash') { player.httpSourceSelector(); if (video_data.params.quality_dash !== "auto") { - player.ready(() => { - player.on("loadedmetadata", () => { - const qualityLevels = Array.from(player.qualityLevels()).sort((a, b) => a.height - b.height); + player.ready(function () { + player.on("loadedmetadata", function () { + const qualityLevels = Array.from(player.qualityLevels()).sort(function (a, b) {return a.height - b.height;}); let targetQualityLevel; switch (video_data.params.quality_dash) { case "best": @@ -391,9 +391,9 @@ if (!video_data.params.listen && video_data.params.annotations) { } } } - } + }; - window.addEventListener('__ar_annotation_click', e => { + window.addEventListener('__ar_annotation_click', function (e) { const { url, target, seconds } = e.detail; var path = new URL(url); @@ -584,7 +584,7 @@ function increase_playback_rate(steps) { player.playbackRate(options.playbackRates[newIndex]); } -window.addEventListener('keydown', e => { +window.addEventListener('keydown', function (e) { if (e.target.tagName.toLowerCase() === 'input') { // Ignore input when focus is on certain elements, e.g. form fields. return; @@ -744,7 +744,7 @@ if (player.share) { // show the preferred caption by default if (player_data.preferred_caption_found) { - player.ready(() => { + player.ready(function () { player.textTracks()[1].mode = 'showing'; }); } From 7940e91cbe537689791c376e3c33bac65511d66e Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 12:49:05 +0300 Subject: [PATCH 20/48] single quotes --- assets/js/handlers.js | 6 ++-- assets/js/player.js | 68 +++++++++++++++++++++---------------------- assets/js/themes.js | 6 ++-- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/assets/js/handlers.js b/assets/js/handlers.js index c2016bc8a..3224e668b 100644 --- a/assets/js/handlers.js +++ b/assets/js/handlers.js @@ -152,14 +152,14 @@ let focused_tag = document.activeElement.tagName.toLowerCase(); const allowed = /^(button|checkbox|file|radio|submit)$/; - if (focused_tag === "textarea") return; - if (focused_tag === "input") { + if (focused_tag === 'textarea') return; + if (focused_tag === 'input') { let focused_type = document.activeElement.type.toLowerCase(); if (!focused_type.match(allowed)) return; } // Focus search bar on '/' - if (event.key === "/") { + if (event.key === '/') { document.getElementById('searchbox').focus(); event.preventDefault(); } diff --git a/assets/js/player.js b/assets/js/player.js index 0c5b28d47..440f880a8 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -39,7 +39,7 @@ embed_url.searchParams.delete('v'); var short_url = location.origin + '/' + video_data.id + embed_url.search; embed_url = location.origin + '/embed/' + video_data.id + embed_url.search; -var save_player_pos_key = "save_player_pos"; +var save_player_pos_key = 'save_player_pos'; videojs.Vhs.xhr.beforeRequest = function(options) { if (options.uri.indexOf('videoplayback') === -1 && options.uri.indexOf('local=true') === -1) { @@ -112,8 +112,8 @@ var shareOptions = { description: player_data.description, image: player_data.thumbnail, get embedCode() { - return ""; + return ''; } }; @@ -138,19 +138,19 @@ if (location.pathname.startsWith('/embed/')) { // Detection code taken from https://stackoverflow.com/a/20293441 function isMobile() { - try{ document.createEvent("TouchEvent"); return true; } + try{ document.createEvent('TouchEvent'); return true; } catch(e){ return false; } } if (isMobile()) { player.mobileUi(); - buttons = ["playToggle", "volumePanel", "captionsButton"]; + buttons = ['playToggle', 'volumePanel', 'captionsButton']; - if (video_data.params.quality !== 'dash') buttons.push("qualitySelector"); + if (video_data.params.quality !== 'dash') buttons.push('qualitySelector'); // Create new control bar object for operation buttons - const ControlBar = videojs.getComponent("controlBar"); + const ControlBar = videojs.getComponent('controlBar'); let operations_bar = new ControlBar(player, { children: [], playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] @@ -158,24 +158,24 @@ if (isMobile()) { buttons.slice(1).forEach(function (child) {operations_bar.addChild(child);}); // Remove operation buttons from primary control bar - primary_control_bar = player.getChild("controlBar"); + primary_control_bar = player.getChild('controlBar'); buttons.forEach(function (child) {primary_control_bar.removeChild(child);}); operations_bar_element = operations_bar.el(); - operations_bar_element.className += " mobile-operations-bar"; + operations_bar_element.className += ' mobile-operations-bar'; player.addChild(operations_bar); // Playback menu doesn't work when it's initialized outside of the primary control bar - playback_element = document.getElementsByClassName("vjs-playback-rate")[0]; + playback_element = document.getElementsByClassName('vjs-playback-rate')[0]; operations_bar_element.append(playback_element); // The share and http source selector element can't be fetched till the players ready. - player.one("playing", function () { - share_element = document.getElementsByClassName("vjs-share-control")[0]; + player.one('playing', function () { + share_element = document.getElementsByClassName('vjs-share-control')[0]; operations_bar_element.append(share_element); if (video_data.params.quality === 'dash') { - http_source_selector = document.getElementsByClassName("vjs-http-source-selector vjs-menu-button")[0]; + http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; operations_bar_element.append(http_source_selector); } }); @@ -183,12 +183,12 @@ if (isMobile()) { // Enable VR video support if (!video_data.params.listen && video_data.vr && video_data.params.vr_mode) { - player.crossOrigin("anonymous"); + player.crossOrigin('anonymous'); switch (video_data.projection_type) { - case "EQUIRECTANGULAR": - player.vr({projection: "equirectangular"}); - default: // Should only be "MESH" but we'll use this as a fallback. - player.vr({projection: "EAC"}); + case 'EQUIRECTANGULAR': + player.vr({projection: 'equirectangular'}); + default: // Should only be 'MESH' but we'll use this as a fallback. + player.vr({projection: 'EAC'}); } } @@ -223,15 +223,15 @@ player.playbackRate(video_data.params.speed); * @returns cookieValue */ function getCookieValue(name) { - var value = document.cookie.split(";").filter(function (item) {return item.includes(name + "=");}); + var value = document.cookie.split(';').filter(function (item) {return item.includes(name + '=');}); return (value.length >= 1) - ? value[0].substring((name + "=").length, value[0].length) + ? value[0].substring((name + '=').length, value[0].length) : null; } /** - * Method for updating the "PREFS" cookie (or creating it if missing) + * Method for updating the 'PREFS' cookie (or creating it if missing) * * @param {number} newVolume New volume defined (null if unchanged) * @param {number} newSpeed New speed defined (null if unchanged) @@ -291,7 +291,7 @@ if (video_data.premiere_timestamp && Math.round(new Date() / 1000) < video_data. if (video_data.params.save_player_pos) { const url = new URL(location); - const hasTimeParam = url.searchParams.has("t"); + const hasTimeParam = url.searchParams.has('t'); const remeberedTime = get_video_time(); let lastUpdated = 0; @@ -307,7 +307,7 @@ if (video_data.params.save_player_pos) { } }; - player.on("timeupdate", updateTime); + player.on('timeupdate', updateTime); } else remove_all_video_times(); @@ -334,16 +334,16 @@ if (video_data.params.autoplay) { if (!video_data.params.listen && video_data.params.quality === 'dash') { player.httpSourceSelector(); - if (video_data.params.quality_dash !== "auto") { + if (video_data.params.quality_dash !== 'auto') { player.ready(function () { - player.on("loadedmetadata", function () { + player.on('loadedmetadata', function () { const qualityLevels = Array.from(player.qualityLevels()).sort(function (a, b) {return a.height - b.height;}); let targetQualityLevel; switch (video_data.params.quality_dash) { - case "best": + case 'best': targetQualityLevel = qualityLevels.length - 1; break; - case "worst": + case 'worst': targetQualityLevel = 0; break; default: @@ -734,7 +734,7 @@ window.addEventListener('keydown', function (e) { }; player.on('mousewheel', mouseScroll); - player.on("DOMMouseScroll", mouseScroll); + player.on('DOMMouseScroll', mouseScroll); }()); // Since videojs-share can sometimes be blocked, we defer it until last @@ -750,7 +750,7 @@ if (player_data.preferred_caption_found) { } // Safari audio double duration fix -if (navigator.vendor === "Apple Computer, Inc." && video_data.params.listen) { +if (navigator.vendor === 'Apple Computer, Inc.' && video_data.params.listen) { player.on('loadedmetadata', function () { player.on('timeupdate', function () { if (player.remainingTime() < player.duration() / 2 && player.remainingTime() >= 2) { @@ -761,17 +761,17 @@ if (navigator.vendor === "Apple Computer, Inc." && video_data.params.listen) { } // Watch on Invidious link -if (window.location.pathname.startsWith("/embed/")) { +if (window.location.pathname.startsWith('/embed/')) { const Button = videojs.getComponent('Button'); let watch_on_invidious_button = new Button(player); // Create hyperlink for current instance - redirect_element = document.createElement("a"); - redirect_element.setAttribute("href", `//${window.location.host}/watch?v=${window.location.pathname.replace("/embed/","")}`); - redirect_element.appendChild(document.createTextNode("Invidious")); + redirect_element = document.createElement('a'); + redirect_element.setAttribute('href', `//${window.location.host}/watch?v=${window.location.pathname.replace('/embed/','')}`); + redirect_element.appendChild(document.createTextNode('Invidious')); watch_on_invidious_button.el().appendChild(redirect_element); - watch_on_invidious_button.addClass("watch-on-invidious"); + watch_on_invidious_button.addClass('watch-on-invidious'); cb = player.getChild('ControlBar'); cb.addChild(watch_on_invidious_button); diff --git a/assets/js/themes.js b/assets/js/themes.js index 2f4680c72..4dabcfc0b 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -3,7 +3,7 @@ var toggle_theme = document.getElementById('toggle_theme'); toggle_theme.href = 'javascript:void(0);'; toggle_theme.addEventListener('click', function () { - var dark_mode = document.body.classList.contains("light-theme"); + var dark_mode = document.body.classList.contains('light-theme'); var url = '/toggle_theme?redirect=false'; var xhr = new XMLHttpRequest(); @@ -49,9 +49,9 @@ function scheme_switch (e) { } } catch {} if (e.matches) { - if (e.media.includes("dark")) { + if (e.media.includes('dark')) { set_mode(true); - } else if (e.media.includes("light")) { + } else if (e.media.includes('light')) { set_mode(false); } } From 352f3640cfbe7930fd6765b4376d7735b39b0219 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 13:03:05 +0300 Subject: [PATCH 21/48] transform template string --- assets/js/player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/player.js b/assets/js/player.js index 440f880a8..e0c9829ef 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -767,7 +767,7 @@ if (window.location.pathname.startsWith('/embed/')) { // Create hyperlink for current instance redirect_element = document.createElement('a'); - redirect_element.setAttribute('href', `//${window.location.host}/watch?v=${window.location.pathname.replace('/embed/','')}`); + redirect_element.setAttribute('href', location.pathname.replace('/embed/', '/watch?v=')); redirect_element.appendChild(document.createTextNode('Invidious')); watch_on_invidious_button.el().appendChild(redirect_element); From 12ab11413f2351fd49e2a0313635a0d181db3403 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 13:04:44 +0300 Subject: [PATCH 22/48] fix double variable declaration --- assets/js/embed.js | 5 +++-- assets/js/watch.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/assets/js/embed.js b/assets/js/embed.js index d3c530cb0..69dcc0531 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -9,12 +9,13 @@ function get_playlist(plid, retries) { return; } + var plid_url; if (plid.startsWith('RD')) { - var plid_url = '/api/v1/mixes/' + plid + + plid_url = '/api/v1/mixes/' + plid + '?continuation=' + video_data.id + '&format=html&hl=' + video_data.preferences.locale; } else { - var plid_url = '/api/v1/playlists/' + plid + + plid_url = '/api/v1/playlists/' + plid + '?index=' + video_data.index + '&continuation' + video_data.id + '&format=html&hl=' + video_data.preferences.locale; diff --git a/assets/js/watch.js b/assets/js/watch.js index ebc779057..1066653cc 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -130,12 +130,13 @@ function get_playlist(plid, retries) {

\
'; + var plid_url; if (plid.startsWith('RD')) { - var plid_url = '/api/v1/mixes/' + plid + + plid_url = '/api/v1/mixes/' + plid + '?continuation=' + video_data.id + '&format=html&hl=' + video_data.preferences.locale; } else { - var plid_url = '/api/v1/playlists/' + plid + + plid_url = '/api/v1/playlists/' + plid + '?index=' + video_data.index + '&continuation=' + video_data.id + '&format=html&hl=' + video_data.preferences.locale; From 9b09d369d90006df847119eb42b9eabd877d0e7b Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 13:23:24 +0300 Subject: [PATCH 23/48] add variable declarations --- assets/js/community.js | 12 ++++++------ assets/js/notifications.js | 2 +- assets/js/player.js | 16 ++++++++-------- assets/js/watch.js | 24 ++++++++++++------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/assets/js/community.js b/assets/js/community.js index eebaf5d8b..0f1d5d9c7 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -11,10 +11,10 @@ String.prototype.supplant = function (o) { function hide_youtube_replies(event) { var target = event.target; - sub_text = target.getAttribute('data-inner-text'); - inner_text = target.getAttribute('data-sub-text'); + var sub_text = target.getAttribute('data-inner-text'); + var inner_text = target.getAttribute('data-sub-text'); - body = target.parentNode.parentNode.children[1]; + var body = target.parentNode.parentNode.children[1]; body.style.display = 'none'; target.innerHTML = sub_text; @@ -26,10 +26,10 @@ function hide_youtube_replies(event) { function show_youtube_replies(event) { var target = event.target; - sub_text = target.getAttribute('data-inner-text'); - inner_text = target.getAttribute('data-sub-text'); + var sub_text = target.getAttribute('data-inner-text'); + var inner_text = target.getAttribute('data-sub-text'); - body = target.parentNode.parentNode.children[1]; + var body = target.parentNode.parentNode.children[1]; body.style.display = ''; target.innerHTML = sub_text; diff --git a/assets/js/notifications.js b/assets/js/notifications.js index 1235fb41e..d7732fb94 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -18,7 +18,7 @@ function get_subscriptions(callback, retries) { xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { - subscriptions = xhr.response; + var subscriptions = xhr.response; callback(subscriptions); } } diff --git a/assets/js/player.js b/assets/js/player.js index e0c9829ef..315fb6185 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -145,7 +145,7 @@ function isMobile() { if (isMobile()) { player.mobileUi(); - buttons = ['playToggle', 'volumePanel', 'captionsButton']; + var buttons = ['playToggle', 'volumePanel', 'captionsButton']; if (video_data.params.quality !== 'dash') buttons.push('qualitySelector'); @@ -158,24 +158,24 @@ if (isMobile()) { buttons.slice(1).forEach(function (child) {operations_bar.addChild(child);}); // Remove operation buttons from primary control bar - primary_control_bar = player.getChild('controlBar'); + var primary_control_bar = player.getChild('controlBar'); buttons.forEach(function (child) {primary_control_bar.removeChild(child);}); - operations_bar_element = operations_bar.el(); + var operations_bar_element = operations_bar.el(); operations_bar_element.className += ' mobile-operations-bar'; player.addChild(operations_bar); // Playback menu doesn't work when it's initialized outside of the primary control bar - playback_element = document.getElementsByClassName('vjs-playback-rate')[0]; + var playback_element = document.getElementsByClassName('vjs-playback-rate')[0]; operations_bar_element.append(playback_element); // The share and http source selector element can't be fetched till the players ready. player.one('playing', function () { - share_element = document.getElementsByClassName('vjs-share-control')[0]; + var share_element = document.getElementsByClassName('vjs-share-control')[0]; operations_bar_element.append(share_element); if (video_data.params.quality === 'dash') { - http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; + var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; operations_bar_element.append(http_source_selector); } }); @@ -766,13 +766,13 @@ if (window.location.pathname.startsWith('/embed/')) { let watch_on_invidious_button = new Button(player); // Create hyperlink for current instance - redirect_element = document.createElement('a'); + var redirect_element = document.createElement('a'); redirect_element.setAttribute('href', location.pathname.replace('/embed/', '/watch?v=')); redirect_element.appendChild(document.createTextNode('Invidious')); watch_on_invidious_button.el().appendChild(redirect_element); watch_on_invidious_button.addClass('watch-on-invidious'); - cb = player.getChild('ControlBar'); + var cb = player.getChild('ControlBar'); cb.addChild(watch_on_invidious_button); } diff --git a/assets/js/watch.js b/assets/js/watch.js index 1066653cc..e435bc7e7 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -9,7 +9,7 @@ String.prototype.supplant = function (o) { }; function toggle_parent(target) { - body = target.parentNode.parentNode.children[1]; + var body = target.parentNode.parentNode.children[1]; if (body.style.display === null || body.style.display === '') { target.innerHTML = '[ + ]'; body.style.display = 'none'; @@ -21,7 +21,7 @@ function toggle_parent(target) { function toggle_comments(event) { var target = event.target; - body = target.parentNode.parentNode.parentNode.children[1]; + var body = target.parentNode.parentNode.parentNode.children[1]; if (body.style.display === null || body.style.display === '') { target.innerHTML = '[ + ]'; body.style.display = 'none'; @@ -44,10 +44,10 @@ function swap_comments(event) { function hide_youtube_replies(event) { var target = event.target; - sub_text = target.getAttribute('data-inner-text'); - inner_text = target.getAttribute('data-sub-text'); + var sub_text = target.getAttribute('data-inner-text'); + var inner_text = target.getAttribute('data-sub-text'); - body = target.parentNode.parentNode.children[1]; + var body = target.parentNode.parentNode.children[1]; body.style.display = 'none'; target.innerHTML = sub_text; @@ -59,10 +59,10 @@ function hide_youtube_replies(event) { function show_youtube_replies(event) { var target = event.target; - sub_text = target.getAttribute('data-inner-text'); - inner_text = target.getAttribute('data-sub-text'); + var sub_text = target.getAttribute('data-inner-text'); + var inner_text = target.getAttribute('data-sub-text'); - body = target.parentNode.parentNode.children[1]; + var body = target.parentNode.parentNode.children[1]; body.style.display = ''; target.innerHTML = sub_text; @@ -118,7 +118,7 @@ function number_with_separator(val) { function get_playlist(plid, retries) { if (retries === undefined) retries = 5; - playlist = document.getElementById('playlist'); + var playlist = document.getElementById('playlist'); if (retries <= 0) { console.log('Failed to pull playlist'); @@ -212,7 +212,7 @@ function get_playlist(plid, retries) { function get_reddit_comments(retries) { if (retries === undefined) retries = 5; - comments = document.getElementById('comments'); + var comments = document.getElementById('comments'); if (retries <= 0) { console.log('Failed to pull comments'); @@ -289,7 +289,7 @@ function get_reddit_comments(retries) { function get_youtube_comments(retries) { if (retries === undefined) retries = 5; - comments = document.getElementById('comments'); + var comments = document.getElementById('comments'); if (retries <= 0) { console.log('Failed to pull comments'); @@ -463,7 +463,7 @@ window.addEventListener('load', function (e) { } else if (video_data.params.comments[1] === 'reddit') { get_reddit_comments(); } else { - comments = document.getElementById('comments'); + var comments = document.getElementById('comments'); comments.innerHTML = ''; } }); From c4cc50ca39a32e9beeb29b6fb7b669adb6b9df98 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 13:40:30 +0300 Subject: [PATCH 24/48] replace innerHTML to safer textContent where possible --- assets/js/community.js | 2 +- assets/js/embed.js | 2 +- assets/js/notifications.js | 2 +- assets/js/player.js | 4 ++-- assets/js/playlist_widget.js | 2 +- assets/js/subscribe_widget.js | 2 +- assets/js/watch.js | 14 +++++++------- assets/js/watched_widget.js | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/assets/js/community.js b/assets/js/community.js index 0f1d5d9c7..58caa71e2 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -1,5 +1,5 @@ 'use strict'; -var community_data = JSON.parse(document.getElementById('community_data').innerHTML); +var community_data = JSON.parse(document.getElementById('community_data').textContent); String.prototype.supplant = function (o) { return this.replace(/{([^{}]*)}/g, function (a, b) { diff --git a/assets/js/embed.js b/assets/js/embed.js index 69dcc0531..492f546bd 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -1,5 +1,5 @@ 'use strict'; -var video_data = JSON.parse(document.getElementById('video_data').innerHTML); +var video_data = JSON.parse(document.getElementById('video_data').textContent); function get_playlist(plid, retries) { if (retries === undefined) retries = 5; diff --git a/assets/js/notifications.js b/assets/js/notifications.js index d7732fb94..5f431a69a 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -1,5 +1,5 @@ 'use strict'; -var notification_data = JSON.parse(document.getElementById('notification_data').innerHTML); +var notification_data = JSON.parse(document.getElementById('notification_data').textContent); var notifications, delivered; diff --git a/assets/js/player.js b/assets/js/player.js index 315fb6185..7f0f8c7ad 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -1,6 +1,6 @@ 'use strict'; -var player_data = JSON.parse(document.getElementById('player_data').innerHTML); -var video_data = JSON.parse(document.getElementById('video_data').innerHTML); +var player_data = JSON.parse(document.getElementById('player_data').textContent); +var video_data = JSON.parse(document.getElementById('video_data').textContent); var options = { preload: 'auto', diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index c7f4805f4..d2f7d74c0 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -1,5 +1,5 @@ 'use strict'; -var playlist_data = JSON.parse(document.getElementById('playlist_data').innerHTML); +var playlist_data = JSON.parse(document.getElementById('playlist_data').textContent); function add_playlist_video(target) { var select = target.parentNode.children[0].children[1]; diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index d44d65da6..6f4d90f6f 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -1,5 +1,5 @@ 'use strict'; -var subscribe_data = JSON.parse(document.getElementById('subscribe_data').innerHTML); +var subscribe_data = JSON.parse(document.getElementById('subscribe_data').textContent); var subscribe_button = document.getElementById('subscribe'); subscribe_button.parentNode['action'] = 'javascript:void(0)'; diff --git a/assets/js/watch.js b/assets/js/watch.js index e435bc7e7..b7a80a18c 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -1,5 +1,5 @@ 'use strict'; -var video_data = JSON.parse(document.getElementById('video_data').innerHTML); +var video_data = JSON.parse(document.getElementById('video_data').textContent); String.prototype.supplant = function (o) { return this.replace(/{([^{}]*)}/g, function (a, b) { @@ -11,10 +11,10 @@ String.prototype.supplant = function (o) { function toggle_parent(target) { var body = target.parentNode.parentNode.children[1]; if (body.style.display === null || body.style.display === '') { - target.innerHTML = '[ + ]'; + target.textContent = '[ + ]'; body.style.display = 'none'; } else { - target.innerHTML = '[ - ]'; + target.textContent = '[ - ]'; body.style.display = ''; } } @@ -23,10 +23,10 @@ function toggle_comments(event) { var target = event.target; var body = target.parentNode.parentNode.parentNode.children[1]; if (body.style.display === null || body.style.display === '') { - target.innerHTML = '[ + ]'; + target.textContent = '[ + ]'; body.style.display = 'none'; } else { - target.innerHTML = '[ - ]'; + target.textContent = '[ - ]'; body.style.display = ''; } } @@ -50,7 +50,7 @@ function hide_youtube_replies(event) { var body = target.parentNode.parentNode.children[1]; body.style.display = 'none'; - target.innerHTML = sub_text; + target.textContent = sub_text; target.onclick = show_youtube_replies; target.setAttribute('data-inner-text', inner_text); target.setAttribute('data-sub-text', sub_text); @@ -65,7 +65,7 @@ function show_youtube_replies(event) { var body = target.parentNode.parentNode.children[1]; body.style.display = ''; - target.innerHTML = sub_text; + target.textContent = sub_text; target.onclick = hide_youtube_replies; target.setAttribute('data-inner-text', inner_text); target.setAttribute('data-sub-text', sub_text); diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index bd037c2be..b597a3c83 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -1,5 +1,5 @@ 'use strict'; -var watched_data = JSON.parse(document.getElementById('watched_data').innerHTML); +var watched_data = JSON.parse(document.getElementById('watched_data').textContent); function mark_watched(target) { var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; From cdd5a9e935edcfc0d836084e5fcdd243867d5372 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 13:42:34 +0300 Subject: [PATCH 25/48] replace huphen-minus to real minus --- assets/js/watch.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/js/watch.js b/assets/js/watch.js index b7a80a18c..5153f1c13 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -14,7 +14,7 @@ function toggle_parent(target) { target.textContent = '[ + ]'; body.style.display = 'none'; } else { - target.textContent = '[ - ]'; + target.textContent = '[ − ]'; body.style.display = ''; } } @@ -26,7 +26,7 @@ function toggle_comments(event) { target.textContent = '[ + ]'; body.style.display = 'none'; } else { - target.textContent = '[ - ]'; + target.textContent = '[ − ]'; body.style.display = ''; } } @@ -238,7 +238,7 @@ function get_reddit_comments(retries) { comments.innerHTML = ' \
\

\ - [ - ] \ + [ − ] \ {title} \

\

\ @@ -316,7 +316,7 @@ function get_youtube_comments(retries) { comments.innerHTML = ' \

\

\ - [ - ] \ + [ − ] \ {commentsText} \

\ \ From 7450cb1f215701f412370b381c1d3441785493c5 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 14:52:41 +0300 Subject: [PATCH 26/48] default parameters --- assets/js/subscribe_widget.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index 6f4d90f6f..771235c16 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -10,7 +10,9 @@ if (subscribe_button.getAttribute('data-type') === 'subscribe') { subscribe_button.onclick = unsubscribe; } -function subscribe(retries = 5) { +function subscribe(retries) { + if (retries === undefined) retries = 5; + if (retries <= 0) { console.log('Failed to subscribe.'); return; @@ -50,7 +52,10 @@ function subscribe(retries = 5) { xhr.send('csrf_token=' + subscribe_data.csrf_token); } -function unsubscribe(retries = 5) { +function unsubscribe(retries) { + if (retries === undefined) + retries = 5; + if (retries <= 0) { console.log('Failed to subscribe'); return; From 1e60b9a3224c5b9b5d5f1a48af5abc839fd5c1b9 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 14:56:00 +0300 Subject: [PATCH 27/48] destructing binding is not supported by IE11 --- assets/js/player.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/assets/js/player.js b/assets/js/player.js index 7f0f8c7ad..4a12e95ce 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -394,7 +394,9 @@ if (!video_data.params.listen && video_data.params.annotations) { }; window.addEventListener('__ar_annotation_click', function (e) { - const { url, target, seconds } = e.detail; + const url = e.detail.url, + target = e.detail.target, + seconds = e.detail.seconds; var path = new URL(url); if (path.href.startsWith('https://www.youtube.com/watch?') && seconds) { From 026ea52445cca3c7f86e6cefa9899f58a13758a7 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 14:57:14 +0300 Subject: [PATCH 28/48] optional catchng is not supported by IE11 --- assets/js/player.js | 2 +- assets/js/themes.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/js/player.js b/assets/js/player.js index 4a12e95ce..3c8cf2193 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -466,7 +466,7 @@ function get_video_time() { return timestamp || 0; } - catch { + catch (e) { return 0; } } diff --git a/assets/js/themes.js b/assets/js/themes.js index 4dabcfc0b..290b538b7 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -14,7 +14,7 @@ toggle_theme.addEventListener('click', function () { set_mode(dark_mode); try { window.localStorage.setItem('dark_mode', dark_mode ? 'dark' : 'light'); - } catch {} + } catch (e) {} xhr.send(); }); @@ -30,7 +30,7 @@ window.addEventListener('DOMContentLoaded', function () { try { // Update localStorage if dark mode preference changed on preferences page window.localStorage.setItem('dark_mode', dark_mode); - } catch {} + } catch (e) {} update_mode(dark_mode); }); @@ -47,7 +47,7 @@ function scheme_switch (e) { if (localStorage.getItem('dark_mode')) { return; } - } catch {} + } catch (exception) {} if (e.matches) { if (e.media.includes('dark')) { set_mode(true); From 3431a1b1def2408a8b4ad26a831e6606b8db11f9 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 20 Apr 2022 16:36:03 +0300 Subject: [PATCH 29/48] `console.warn` and `info` instead of `log` --- assets/js/community.js | 2 +- assets/js/embed.js | 6 +++--- assets/js/notifications.js | 8 ++++---- assets/js/player.js | 6 +++--- assets/js/subscribe_widget.js | 12 ++++++------ assets/js/watch.js | 22 +++++++++++----------- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/assets/js/community.js b/assets/js/community.js index 58caa71e2..44066a585 100644 --- a/assets/js/community.js +++ b/assets/js/community.js @@ -96,7 +96,7 @@ function get_youtube_replies(target, load_more) { }; xhr.ontimeout = function () { - console.log('Pulling comments failed.'); + console.warn('Pulling comments failed.'); body.innerHTML = fallback; }; diff --git a/assets/js/embed.js b/assets/js/embed.js index 492f546bd..7e9ac6051 100644 --- a/assets/js/embed.js +++ b/assets/js/embed.js @@ -5,7 +5,7 @@ function get_playlist(plid, retries) { if (retries === undefined) retries = 5; if (retries <= 0) { - console.log('Failed to pull playlist'); + console.warn('Failed to pull playlist'); return; } @@ -62,12 +62,12 @@ function get_playlist(plid, retries) { }; xhr.onerror = function () { - console.log('Pulling playlist failed... ' + retries + '/5'); + console.warn('Pulling playlist failed... ' + retries + '/5'); setTimeout(function () { get_playlist(plid, retries - 1); }, 1000); }; xhr.ontimeout = function () { - console.log('Pulling playlist failed... ' + retries + '/5'); + console.warn('Pulling playlist failed... ' + retries + '/5'); get_playlist(plid, retries - 1); }; diff --git a/assets/js/notifications.js b/assets/js/notifications.js index 5f431a69a..ec5f6dd30 100644 --- a/assets/js/notifications.js +++ b/assets/js/notifications.js @@ -25,12 +25,12 @@ function get_subscriptions(callback, retries) { }; xhr.onerror = function () { - console.log('Pulling subscriptions failed... ' + retries + '/5'); + console.warn('Pulling subscriptions failed... ' + retries + '/5'); setTimeout(function () { get_subscriptions(callback, retries - 1); }, 1000); }; xhr.ontimeout = function () { - console.log('Pulling subscriptions failed... ' + retries + '/5'); + console.warn('Pulling subscriptions failed... ' + retries + '/5'); get_subscriptions(callback, retries - 1); }; @@ -54,7 +54,7 @@ function create_notification_stream(subscriptions) { } var notification = JSON.parse(event.data); - console.log('Got notification:', notification); + console.info('Got notification:', notification); if (start_time < notification.published && !delivered.includes(notification.videoId)) { if (Notification.permission === 'granted') { @@ -90,7 +90,7 @@ function create_notification_stream(subscriptions) { } function handle_notification_error(event) { - console.log('Something went wrong with notifications, trying to reconnect...'); + console.warn('Something went wrong with notifications, trying to reconnect...'); notifications = { close: function () { } }; setTimeout(function () { get_subscriptions(create_notification_stream); }, 1000); } diff --git a/assets/js/player.js b/assets/js/player.js index 3c8cf2193..f07031ace 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -280,7 +280,7 @@ player.on('volumechange', function () { player.on('waiting', function () { if (player.playbackRate() > 1 && player.liveTracker.isLive() && player.liveTracker.atLiveEdge()) { - console.log('Player has caught up to source, resetting playbackRate.'); + console.info('Player has caught up to source, resetting playbackRate.'); player.playbackRate(1); } }); @@ -477,7 +477,7 @@ function set_all_video_times(times) { try { storage.setItem(save_player_pos_key, JSON.stringify(times)); } catch (e) { - console.debug('set_all_video_times: ' + e); + console.warn('set_all_video_times: ' + e); } } else { storage.removeItem(save_player_pos_key); @@ -492,7 +492,7 @@ function get_all_video_times() { try { return JSON.parse(raw); } catch (e) { - console.debug('get_all_video_times: ' + e); + console.warn('get_all_video_times: ' + e); } } } diff --git a/assets/js/subscribe_widget.js b/assets/js/subscribe_widget.js index 771235c16..45ff5706e 100644 --- a/assets/js/subscribe_widget.js +++ b/assets/js/subscribe_widget.js @@ -14,7 +14,7 @@ function subscribe(retries) { if (retries === undefined) retries = 5; if (retries <= 0) { - console.log('Failed to subscribe.'); + console.warn('Failed to subscribe.'); return; } @@ -40,12 +40,12 @@ function subscribe(retries) { }; xhr.onerror = function () { - console.log('Subscribing failed... ' + retries + '/5'); + console.warn('Subscribing failed... ' + retries + '/5'); setTimeout(function () { subscribe(retries - 1); }, 1000); }; xhr.ontimeout = function () { - console.log('Subscribing failed... ' + retries + '/5'); + console.warn('Subscribing failed... ' + retries + '/5'); subscribe(retries - 1); }; @@ -57,7 +57,7 @@ function unsubscribe(retries) { retries = 5; if (retries <= 0) { - console.log('Failed to subscribe'); + console.warn('Failed to subscribe'); return; } @@ -83,12 +83,12 @@ function unsubscribe(retries) { }; xhr.onerror = function () { - console.log('Unsubscribing failed... ' + retries + '/5'); + console.warn('Unsubscribing failed... ' + retries + '/5'); setTimeout(function () { unsubscribe(retries - 1); }, 1000); }; xhr.ontimeout = function () { - console.log('Unsubscribing failed... ' + retries + '/5'); + console.warn('Unsubscribing failed... ' + retries + '/5'); unsubscribe(retries - 1); }; diff --git a/assets/js/watch.js b/assets/js/watch.js index 5153f1c13..29d58be52 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -121,7 +121,7 @@ function get_playlist(plid, retries) { var playlist = document.getElementById('playlist'); if (retries <= 0) { - console.log('Failed to pull playlist'); + console.warn('Failed to pull playlist'); playlist.innerHTML = ''; return; } @@ -194,7 +194,7 @@ function get_playlist(plid, retries) { playlist.innerHTML = '


'; - console.log('Pulling playlist timed out... ' + retries + '/5'); + console.warn('Pulling playlist timed out... ' + retries + '/5'); setTimeout(function () { get_playlist(plid, retries - 1); }, 1000); }; @@ -203,7 +203,7 @@ function get_playlist(plid, retries) { playlist.innerHTML = '


'; - console.log('Pulling playlist timed out... ' + retries + '/5'); + console.warn('Pulling playlist timed out... ' + retries + '/5'); get_playlist(plid, retries - 1); }; @@ -215,7 +215,7 @@ function get_reddit_comments(retries) { var comments = document.getElementById('comments'); if (retries <= 0) { - console.log('Failed to pull comments'); + console.warn('Failed to pull comments'); comments.innerHTML = ''; return; } @@ -265,7 +265,7 @@ function get_reddit_comments(retries) { comments.children[0].children[1].children[0].onclick = swap_comments; } else { if (video_data.params.comments[1] === 'youtube') { - console.log('Pulling comments failed... ' + retries + '/5'); + console.warn('Pulling comments failed... ' + retries + '/5'); setTimeout(function () { get_youtube_comments(retries - 1); }, 1000); } else { comments.innerHTML = fallback; @@ -275,12 +275,12 @@ function get_reddit_comments(retries) { }; xhr.onerror = function () { - console.log('Pulling comments failed... ' + retries + '/5'); + console.warn('Pulling comments failed... ' + retries + '/5'); setTimeout(function () { get_reddit_comments(retries - 1); }, 1000); }; xhr.ontimeout = function () { - console.log('Pulling comments failed... ' + retries + '/5'); + console.warn('Pulling comments failed... ' + retries + '/5'); get_reddit_comments(retries - 1); }; @@ -292,7 +292,7 @@ function get_youtube_comments(retries) { var comments = document.getElementById('comments'); if (retries <= 0) { - console.log('Failed to pull comments'); + console.warn('Failed to pull comments'); comments.innerHTML = ''; return; } @@ -349,14 +349,14 @@ function get_youtube_comments(retries) { xhr.onerror = function () { comments.innerHTML = '

'; - console.log('Pulling comments failed... ' + retries + '/5'); + console.warn('Pulling comments failed... ' + retries + '/5'); setTimeout(function () { get_youtube_comments(retries - 1); }, 1000); }; xhr.ontimeout = function () { comments.innerHTML = '

'; - console.log('Pulling comments failed... ' + retries + '/5'); + console.warn('Pulling comments failed... ' + retries + '/5'); get_youtube_comments(retries - 1); }; @@ -417,7 +417,7 @@ function get_youtube_replies(target, load_more, load_replies) { }; xhr.ontimeout = function () { - console.log('Pulling comments failed.'); + console.warn('Pulling comments failed.'); body.innerHTML = fallback; }; From fafd4d93968f36f4b0f713eaef154ac0dc30de87 Mon Sep 17 00:00:00 2001 From: meow Date: Mon, 25 Apr 2022 13:14:08 +0300 Subject: [PATCH 30/48] new lines in the end of file --- assets/js/playlist_widget.js | 2 +- assets/js/themes.js | 2 -- assets/js/watched_widget.js | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/assets/js/playlist_widget.js b/assets/js/playlist_widget.js index d2f7d74c0..c2565874d 100644 --- a/assets/js/playlist_widget.js +++ b/assets/js/playlist_widget.js @@ -71,4 +71,4 @@ function remove_playlist_item(target) { }; xhr.send('csrf_token=' + playlist_data.csrf_token); -} \ No newline at end of file +} diff --git a/assets/js/themes.js b/assets/js/themes.js index 290b538b7..36556a0be 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -88,5 +88,3 @@ function update_mode (mode) { } // else do nothing, falling back to the mode defined by the `dark_mode` preference on the preferences page (backend) } - - diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index b597a3c83..87989a795 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -48,4 +48,4 @@ function mark_unwatched(target) { }; xhr.send('csrf_token=' + watched_data.csrf_token); -} \ No newline at end of file +} From 0503d2a9f307538f595be53ae1e9e8713f1e95ac Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Wed, 27 Apr 2022 00:20:48 +0200 Subject: [PATCH 31/48] Fix 'adaptiveFormats' not available for livestreams in videos API --- src/invidious/routes/api/manifest.cr | 6 ++++++ src/invidious/videos.cr | 24 +++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr index 23d11f65f..d77389a8a 100644 --- a/src/invidious/routes/api/manifest.cr +++ b/src/invidious/routes/api/manifest.cr @@ -62,6 +62,9 @@ module Invidious::Routes::API::Manifest xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true) do mime_streams.each do |fmt| + # OFT streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415) + next if !(fmt.has_key?("indexRange") && fmt.has_key?("initRange")) + codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"') bandwidth = fmt["bitrate"].as_i itag = fmt["itag"].as_i @@ -90,6 +93,9 @@ module Invidious::Routes::API::Manifest heights = [] of Int32 xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true, scanType: "progressive") do mime_streams.each do |fmt| + # OFT streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415) + next if !(fmt.has_key?("indexRange") && fmt.has_key?("initRange")) + codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"') bandwidth = fmt["bitrate"].as_i itag = fmt["itag"].as_i diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 31ae90c7a..7e37cf123 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -374,18 +374,25 @@ struct Video json.array do self.adaptive_fmts.each do |fmt| json.object do - json.field "index", "#{fmt["indexRange"]["start"]}-#{fmt["indexRange"]["end"]}" - json.field "bitrate", fmt["bitrate"].as_i.to_s - json.field "init", "#{fmt["initRange"]["start"]}-#{fmt["initRange"]["end"]}" + # Only available on regular videos, not livestreams/OFT streams + if init_range = fmt["initRange"]? + json.field "init", "#{init_range["start"]}-#{init_range["end"]}" + end + if index_range = fmt["indexRange"]? + json.field "index", "#{index_range["start"]}-#{index_range["end"]}" + end + + # Not available on MPEG-4 Timed Text (`text/mp4`) streams (livestreams only) + json.field "bitrate", fmt["bitrate"].as_i.to_s if fmt["bitrate"]? + json.field "url", fmt["url"] json.field "itag", fmt["itag"].as_i.to_s json.field "type", fmt["mimeType"] - json.field "clen", fmt["contentLength"] + json.field "clen", fmt["contentLength"]? || "-1" json.field "lmt", fmt["lastModified"] json.field "projectionType", fmt["projectionType"] - fmt_info = itag_to_metadata?(fmt["itag"]) - if fmt_info + if fmt_info = itag_to_metadata?(fmt["itag"]) fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.as_i || 30 json.field "fps", fps json.field "container", fmt_info["ext"] @@ -612,6 +619,7 @@ struct Video fmt["url"] = JSON::Any.new("#{fmt["url"]}&host=#{URI.parse(fmt["url"].as_s).host}") fmt["url"] = JSON::Any.new("#{fmt["url"]}®ion=#{self.info["region"]}") if self.info["region"]? end + fmt_stream.sort_by! { |f| f["width"]?.try &.as_i || 0 } @fmt_stream = fmt_stream return @fmt_stream.as(Array(Hash(String, JSON::Any))) @@ -631,9 +639,7 @@ struct Video fmt["url"] = JSON::Any.new("#{fmt["url"]}&host=#{URI.parse(fmt["url"].as_s).host}") fmt["url"] = JSON::Any.new("#{fmt["url"]}®ion=#{self.info["region"]}") if self.info["region"]? end - # See https://github.com/TeamNewPipe/NewPipe/issues/2415 - # Some streams are segmented by URL `sq/` rather than index, for now we just filter them out - fmt_stream.reject! { |f| !f["indexRange"]? } + fmt_stream.sort_by! { |f| f["width"]?.try &.as_i || 0 } @adaptive_fmts = fmt_stream return @adaptive_fmts.as(Array(Hash(String, JSON::Any))) From 8144308aee078d2322491e9848247df7257d756b Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Wed, 27 Apr 2022 00:21:23 +0200 Subject: [PATCH 32/48] Add extra data to 'adaptiveFormats' in videos API --- src/invidious/videos.cr | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 7e37cf123..cb860032a 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -412,6 +412,15 @@ struct Video end end end + + # Audio-related data + json.field "audioQuality", fmt["audioQuality"] if fmt.has_key?("audioQuality") + json.field "audioSampleRate", fmt["audioSampleRate"].as_s.to_i if fmt.has_key?("audioSampleRate") + json.field "audioChannels", fmt["audioChannels"] if fmt.has_key?("audioChannels") + + # Extra misc stuff + json.field "colorInfo", fmt["colorInfo"] if fmt.has_key?("colorInfo") + json.field "captionTrack", fmt["captionTrack"] if fmt.has_key?("captionTrack") end end end From dbb1e3f5d8aae3d732bbf3ccf82baec0739d9445 Mon Sep 17 00:00:00 2001 From: meow Date: Wed, 27 Apr 2022 15:01:34 +0300 Subject: [PATCH 33/48] replace tabs to spaces --- assets/js/player.js | 14 +++++++------- assets/js/themes.js | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/assets/js/player.js b/assets/js/player.js index f07031ace..6ddb11586 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -171,14 +171,14 @@ if (isMobile()) { // The share and http source selector element can't be fetched till the players ready. player.one('playing', function () { - var share_element = document.getElementsByClassName('vjs-share-control')[0]; - operations_bar_element.append(share_element); + var share_element = document.getElementsByClassName('vjs-share-control')[0]; + operations_bar_element.append(share_element); - if (video_data.params.quality === 'dash') { - var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; - operations_bar_element.append(http_source_selector); - } - }); + if (video_data.params.quality === 'dash') { + var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; + operations_bar_element.append(http_source_selector); + } + }); } // Enable VR video support diff --git a/assets/js/themes.js b/assets/js/themes.js index 36556a0be..3f503b385 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -78,10 +78,10 @@ function update_mode (mode) { // If preference for dark mode indicated set_mode(true); } - else if (mode === 'false' /* for backwards compatibility */ || mode === 'light') { - // If preference for light mode indicated - set_mode(false); - } + else if (mode === 'false' /* for backwards compatibility */ || mode === 'light') { + // If preference for light mode indicated + set_mode(false); + } else if (document.getElementById('dark_mode_pref').textContent === '' && window.matchMedia('(prefers-color-scheme: dark)').matches) { // If no preference indicated here and no preference indicated on the preferences page (backend), but the browser tells us that the operating system has a dark theme set_mode(true); From b7f0b054b85e60ae7c91144cb44d8139e468b23a Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Wed, 27 Apr 2022 21:44:31 +0200 Subject: [PATCH 34/48] It's OTF, not OFT --- src/invidious/routes/api/manifest.cr | 4 ++-- src/invidious/videos.cr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr index d77389a8a..8bc36946b 100644 --- a/src/invidious/routes/api/manifest.cr +++ b/src/invidious/routes/api/manifest.cr @@ -62,7 +62,7 @@ module Invidious::Routes::API::Manifest xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true) do mime_streams.each do |fmt| - # OFT streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415) + # OTF streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415) next if !(fmt.has_key?("indexRange") && fmt.has_key?("initRange")) codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"') @@ -93,7 +93,7 @@ module Invidious::Routes::API::Manifest heights = [] of Int32 xml.element("AdaptationSet", id: i, mimeType: mime_type, startWithSAP: 1, subsegmentAlignment: true, scanType: "progressive") do mime_streams.each do |fmt| - # OFT streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415) + # OTF streams aren't supported yet (See https://github.com/TeamNewPipe/NewPipe/issues/2415) next if !(fmt.has_key?("indexRange") && fmt.has_key?("initRange")) codecs = fmt["mimeType"].as_s.split("codecs=")[1].strip('"') diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index cb860032a..27c2b6d12 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -374,7 +374,7 @@ struct Video json.array do self.adaptive_fmts.each do |fmt| json.object do - # Only available on regular videos, not livestreams/OFT streams + # Only available on regular videos, not livestreams/OTF streams if init_range = fmt["initRange"]? json.field "init", "#{init_range["start"]}-#{init_range["end"]}" end From 64fe4de3fb2bbc7e33bf0321ae42b484bb0269e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milien=20Devos?= Date: Fri, 29 Apr 2022 06:16:54 +0000 Subject: [PATCH 35/48] bump to crystal 1.4.1 --- docker/Dockerfile | 2 +- docker/Dockerfile.arm64 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 178c758fb..1346f6ebf 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM crystallang/crystal:1.4.0-alpine AS builder +FROM crystallang/crystal:1.4.1-alpine AS builder RUN apk add --no-cache sqlite-static yaml-static ARG release diff --git a/docker/Dockerfile.arm64 b/docker/Dockerfile.arm64 index abfbb9b76..75cab819b 100644 --- a/docker/Dockerfile.arm64 +++ b/docker/Dockerfile.arm64 @@ -1,5 +1,5 @@ FROM alpine:edge AS builder -RUN apk add --no-cache 'crystal=1.4.0-r0' shards sqlite-static yaml-static yaml-dev libxml2-dev zlib-static openssl-libs-static openssl-dev musl-dev +RUN apk add --no-cache 'crystal=1.4.1-r0' shards sqlite-static yaml-static yaml-dev libxml2-dev zlib-static openssl-libs-static openssl-dev musl-dev ARG release From 1f08d2929c85766ec6666d29b79d08d52c82f953 Mon Sep 17 00:00:00 2001 From: 138138138 <78271024+138138138@users.noreply.github.com> Date: Sat, 30 Apr 2022 16:55:12 +0800 Subject: [PATCH 36/48] Fix iOS 3 buttons separated lines --- assets/css/default.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/css/default.css b/assets/css/default.css index 49069c92f..61b7819fc 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -291,7 +291,7 @@ input[type="search"]::-webkit-search-cancel-button { .flexible { display: flex; } .flex-left { flex: 1 1 100%; flex-wrap: wrap; } -.flex-right { flex: 1 0 max-content; flex-wrap: nowrap; } +.flex-right { flex: 1 0 auto; flex-wrap: nowrap; } p.channel-name { margin: 0; } p.video-data { margin: 0; font-weight: bold; font-size: 80%; } From 595c3fb833c5744fc83f0936a11cb8c16393190e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milien=20Devos?= Date: Sat, 30 Apr 2022 23:42:38 +0200 Subject: [PATCH 37/48] Revert "Youtube verification badge" (#3070) --- src/invidious/channels/about.cr | 7 +-- src/invidious/comments.cr | 8 +--- src/invidious/helpers/serialized_yt_data.cr | 7 +-- src/invidious/routes/feeds.cr | 1 - src/invidious/videos.cr | 14 ------ src/invidious/views/channel.ecr | 2 +- src/invidious/views/community.ecr | 2 +- src/invidious/views/components/item.ecr | 6 +-- src/invidious/views/playlists.ecr | 2 +- src/invidious/views/watch.ecr | 6 +-- src/invidious/yt_backend/extractors.cr | 48 ++++++--------------- 11 files changed, 26 insertions(+), 77 deletions(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index d48fd1fb9..4f82a0f1f 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -12,8 +12,7 @@ record AboutChannel, joined : Time, is_family_friendly : Bool, allowed_regions : Array(String), - tabs : Array(String), - verified : Bool + tabs : Array(String) record AboutRelatedChannel, ucid : String, @@ -71,9 +70,6 @@ def get_about_info(ucid, locale) : AboutChannel # if banner.includes? "channels/c4/default_banner" # banner = nil # end - # author_verified_badges = initdata["header"]?.try &.["c4TabbedHeaderRenderer"]?.try &.["badges"]? - author_verified_badge = initdata["header"].dig?("c4TabbedHeaderRenderer", "badges", 0, "metadataBadgeRenderer", "tooltip") - author_verified = (author_verified_badge && author_verified_badge == "Verified") description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" description_html = HTML.escape(description) @@ -132,7 +128,6 @@ def get_about_info(ucid, locale) : AboutChannel is_family_friendly: is_family_friendly, allowed_regions: allowed_regions, tabs: tabs, - verified: author_verified || false, ) end diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 3ae49aa6d..c6e7fd174 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -146,8 +146,6 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" author = node_comment["authorText"]?.try &.["simpleText"]? || "" - json.field "verified", (node_comment["authorCommentBadge"]? != nil) - json.field "author", author json.field "authorThumbnails" do json.array do @@ -331,11 +329,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) - if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool - author_name += " " - elsif child["verified"]?.try &.as_bool - author_name += " " - end + html << <<-END_HTML
diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index 3918bd130..bfbc237ce 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -12,7 +12,6 @@ struct SearchVideo property live_now : Bool property premium : Bool property premiere_timestamp : Time? - property author_verified : Bool def to_xml(auto_generated, query_params, xml : XML::Builder) query_params["v"] = self.id @@ -130,7 +129,6 @@ struct SearchPlaylist property video_count : Int32 property videos : Array(SearchPlaylistVideo) property thumbnail : String? - property author_verified : Bool def to_json(locale : String?, json : JSON::Builder) json.object do @@ -143,8 +141,6 @@ struct SearchPlaylist json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" - json.field "authorVerified", self.author_verified - json.field "videoCount", self.video_count json.field "videos" do json.array do @@ -186,7 +182,6 @@ struct SearchChannel property video_count : Int32 property description_html : String property auto_generated : Bool - property author_verified : Bool def to_json(locale : String?, json : JSON::Builder) json.object do @@ -194,7 +189,7 @@ struct SearchChannel json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" - json.field "authorVerified", self.author_verified + json.field "authorThumbnails" do json.array do qualities = {32, 48, 76, 100, 176, 512} diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr index b5b583996..f7f7b426a 100644 --- a/src/invidious/routes/feeds.cr +++ b/src/invidious/routes/feeds.cr @@ -182,7 +182,6 @@ module Invidious::Routes::Feeds paid: false, premium: false, premiere_timestamp: nil, - author_verified: false, # ¯\_(ツ)_/¯ }) end diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 4cb049caf..27c2b6d12 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -609,10 +609,6 @@ struct Video info["authorThumbnail"]?.try &.as_s || "" end - def author_verified : Bool - info["authorVerified"].try &.as_bool || false - end - def sub_count_text : String info["subCountText"]?.try &.as_s || "-" end @@ -864,12 +860,6 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? .try &.dig?("runs", 0) author = channel_info.try &.dig?("text") - author_verified_badge = related["ownerBadges"]?.try do |badges_array| - badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") - end - - author_verified = (author_verified_badge && author_verified_badge.size > 0).to_s - ucid = channel_info.try { |ci| HelperExtractors.get_browse_id(ci) } # "4,088,033 views", only available on compact renderer @@ -893,7 +883,6 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? "length_seconds" => JSON::Any.new(length || "0"), "view_count" => JSON::Any.new(view_count || "0"), "short_view_count" => JSON::Any.new(short_view_count || "0"), - "author_verified" => JSON::Any.new(author_verified), } end @@ -1088,9 +1077,6 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") - author_verified_badge = author_info.try &.dig?("badges", 0, "metadataBadgeRenderer", "tooltip") - params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge == "Verified")) - params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 92f81ee49..40b553a9c 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,7 +20,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 3bc29e552..f0add06bf 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index fb7ad1dc7..ce7af783f 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

+

<%= HTML.escape(item.author) %>

<% when MixVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index c8718e7b7..12dba088f 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,7 +19,7 @@
- <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %> + <%= author %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 8b6eb903a..2e493f4cc 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -207,7 +207,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %> + <%= author %>
@@ -281,9 +281,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + "><%= rv["author"]? %> <% else %> - <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> + <%= rv["author"]? %> <% end %>
diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index 4657bb1d9..ce39bc284 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -102,11 +102,7 @@ private module Parsers premium = false premiere_timestamp = item_contents.dig?("upcomingEventData", "startTime").try { |t| Time.unix(t.as_s.to_i64) } - author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| - badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") - end - author_verified = (author_verified_badge && author_verified_badge.size > 0) item_contents["badges"]?.try &.as_a.each do |badge| b = badge["metadataBadgeRenderer"] case b["label"].as_s @@ -133,7 +129,6 @@ private module Parsers live_now: live_now, premium: premium, premiere_timestamp: premiere_timestamp, - author_verified: author_verified || false, }) end @@ -161,11 +156,7 @@ private module Parsers private def self.parse(item_contents, author_fallback) author = extract_text(item_contents["title"]) || author_fallback.name author_id = item_contents["channelId"]?.try &.as_s || author_fallback.id - author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| - badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") - end - author_verified = (author_verified_badge && author_verified_badge.size > 0) author_thumbnail = HelperExtractors.get_thumbnails(item_contents) # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. # Always simpleText @@ -188,7 +179,6 @@ private module Parsers video_count: video_count, description_html: description_html, auto_generated: auto_generated, - author_verified: author_verified || false, }) end @@ -216,23 +206,18 @@ private module Parsers private def self.parse(item_contents, author_fallback) title = extract_text(item_contents["title"]) || "" plid = item_contents["playlistId"]?.try &.as_s || "" - author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| - badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") - end - author_verified = (author_verified_badge && author_verified_badge.size > 0) video_count = HelperExtractors.get_video_count(item_contents) playlist_thumbnail = HelperExtractors.get_thumbnails(item_contents) SearchPlaylist.new({ - title: title, - id: plid, - author: author_fallback.name, - ucid: author_fallback.id, - video_count: video_count, - videos: [] of SearchPlaylistVideo, - thumbnail: playlist_thumbnail, - author_verified: author_verified || false, + title: title, + id: plid, + author: author_fallback.name, + ucid: author_fallback.id, + video_count: video_count, + videos: [] of SearchPlaylistVideo, + thumbnail: playlist_thumbnail, }) end @@ -266,11 +251,7 @@ private module Parsers author_info = item_contents.dig?("shortBylineText", "runs", 0) author = author_info.try &.["text"].as_s || author_fallback.name author_id = author_info.try { |x| HelperExtractors.get_browse_id(x) } || author_fallback.id - author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| - badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") - end - author_verified = (author_verified_badge && author_verified_badge.size > 0) videos = item_contents["videos"]?.try &.as_a.map do |v| v = v["childVideoRenderer"] v_title = v.dig?("title", "simpleText").try &.as_s || "" @@ -286,14 +267,13 @@ private module Parsers # TODO: item_contents["publishedTimeText"]? SearchPlaylist.new({ - title: title, - id: plid, - author: author, - ucid: author_id, - video_count: video_count, - videos: videos, - thumbnail: playlist_thumbnail, - author_verified: author_verified || false, + title: title, + id: plid, + author: author, + ucid: author_id, + video_count: video_count, + videos: videos, + thumbnail: playlist_thumbnail, }) end From 383238393635ac15eca2794473fd18d2f19d2a80 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 1 May 2022 11:13:03 +0200 Subject: [PATCH 38/48] Update English (United States) translation Co-authored-by: Samantaz Fox --- locales/en-US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en-US.json b/locales/en-US.json index c57670fca..7518c3a1b 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -68,7 +68,7 @@ "preferences_watch_history_label": "Enable watch history: ", "preferences_speed_label": "Default speed: ", "preferences_quality_label": "Preferred video quality: ", - "preferences_quality_option_dash": "DASH (adaptative quality)", + "preferences_quality_option_dash": "DASH (adaptive quality)", "preferences_quality_option_hd720": "HD720", "preferences_quality_option_medium": "Medium", "preferences_quality_option_small": "Small", From 62fadb54ee59f4006898bba3e2d5d9a02d6f4e8a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 1 May 2022 11:13:03 +0200 Subject: [PATCH 39/48] Update Hungarian translation Co-authored-by: f3rr31 <5920873@disroot.org> --- locales/hu-HU.json | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/locales/hu-HU.json b/locales/hu-HU.json index a36798134..50e505dc8 100644 --- a/locales/hu-HU.json +++ b/locales/hu-HU.json @@ -31,15 +31,15 @@ "No": "Nem", "Import and Export Data": "Adatok importálása és exportálása", "Import": "Importálás", - "Import Invidious data": "Az Invidious adatainak importálása", - "Import YouTube subscriptions": "YouTube-feliratkozások importálása", + "Import Invidious data": "Az Invidious JSON-adatainak importálása", + "Import YouTube subscriptions": "YouTube- vagy OPML-feliratkozások importálása", "Import FreeTube subscriptions (.db)": "FreeTube-feliratkozások importálása (.db)", "Import NewPipe subscriptions (.json)": "NewPipe-feliratkozások importálása (.json)", "Import NewPipe data (.zip)": "NewPipe adatainak importálása (.zip)", "Export": "Exportálás", "Export subscriptions as OPML": "Feliratkozások exportálása OPML-ként", "Export subscriptions as OPML (for NewPipe & FreeTube)": "Feliratkozások exportálása OPML-ként (NewPipe-hoz és FreeTube-hoz)", - "Export data as JSON": "Adat exportálása JSON-ként", + "Export data as JSON": "Az Invidious JSON-adatainak exportálása", "Delete account?": "Törlésre kerüljön a fiók?", "History": "Megnézett videók naplója", "An alternative front-end to YouTube": "Ez az oldal egyike a YouTube alternatív kezelőfelületeinek", @@ -159,7 +159,7 @@ "Engagement: ": "Visszajelzési mutató: ", "Whitelisted regions: ": "Engedélyezett régiók: ", "Blacklisted regions: ": "Tiltott régiók: ", - "Shared `x`": "`x` napon osztották meg", + "Shared `x`": "`x` dátummal osztották meg", "Premieres in `x`": "`x` később lesz a premierje", "Premieres `x`": "`x` lesz a premierje", "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Helló! Úgy tűnik a JavaScript ki van kapcsolva a böngészőben. Ide kattintva lehet olvasni a hozzászólásokat, de a betöltésük így kicsit több időbe telik.", @@ -366,13 +366,13 @@ "invidious": "Invidious", "videoinfo_started_streaming_x_ago": "`x` ezelőtt kezdte streamelni", "search_filters_sort_option_views": "Mennyien látták", - "search_filters_features_option_purchased": "Megvásárolva", - "search_filters_features_option_three_sixty": "360°-os", + "search_filters_features_option_purchased": "Megvásárolt", + "search_filters_features_option_three_sixty": "360°-os virtuális valóság", "footer_original_source_code": "Eredeti forráskód", "none": "egyik sem", "videoinfo_watch_on_youTube": "YouTube-on megnézni", "videoinfo_youTube_embed_link": "beágyazva", - "videoinfo_invidious_embed_link": "Beágyazás linkje", + "videoinfo_invidious_embed_link": "Beágyazott hivatkozás", "download_subtitles": "Felirat – `x` (.vtt)", "user_created_playlists": "`x` létrehozott lejátszási lista", "user_saved_playlists": "`x` mentett lejátszási lista", @@ -459,5 +459,16 @@ "Dutch (auto-generated)": "holland (automatikusan generált)", "French (auto-generated)": "francia (automatikusan generált)", "Vietnamese (auto-generated)": "vietnámi (automatikusan generált)", - "search_filters_title": "Szűrők" + "search_filters_title": "Szűrők", + "preferences_watch_history_label": "Megnézett videók naplózása: ", + "search_message_no_results": "Nincs találat.", + "search_message_change_filters_or_query": "Próbálj meg bővebben rákeresni vagy a szűrőkön állítani.", + "search_message_use_another_instance": " Megpróbálhatod egy másik Invidious-oldalon is a keresést.", + "search_filters_date_label": "Feltöltés ideje", + "search_filters_date_option_none": "Mindegy mikor", + "search_filters_type_option_all": "Bármilyen", + "search_filters_duration_option_none": "Mindegy", + "search_filters_duration_option_medium": "Átlagos (4 és 20 perc között)", + "search_filters_features_option_vr180": "180°-os virtuális valóság", + "search_filters_apply_button": "Keresés a megadott szűrőkkel" } From dbe49610a1bb424225ebb84bdd2a0c38367642f9 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 1 May 2022 11:13:03 +0200 Subject: [PATCH 40/48] Update Russian translation Co-authored-by: AHOHNMYC --- locales/ru.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index 88bb64adc..a10bb0502 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -476,5 +476,15 @@ "preferences_save_player_pos_label": "Запоминать позицию: ", "preferences_region_label": "Страна: ", "preferences_watch_history_label": "Включить историю просмотров ", - "search_filters_title": "Фильтр" + "search_filters_title": "Фильтр", + "search_filters_duration_option_none": "Любой длины", + "search_filters_type_option_all": "Любого типа", + "search_filters_date_option_none": "Любой даты", + "search_filters_date_label": "Дата загрузки", + "search_message_no_results": "Ничего не найдено.", + "search_message_use_another_instance": " Дополнительно вы можете поискать на других зеркалах.", + "search_filters_features_option_vr180": "VR180", + "search_message_change_filters_or_query": "Попробуйте расширить поисковый запрос и изменить фильтры.", + "search_filters_duration_option_medium": "Средние (4 - 20 минут)", + "search_filters_apply_button": "Применить фильтры" } From 96afc1a45d1e8df0f00d6c4cde9e9744cc9f1fcd Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 1 May 2022 13:40:02 +0200 Subject: [PATCH 41/48] Revert html escaping of backtrace --- src/invidious/helpers/errors.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr index 2eab6263a..b80dcdaf5 100644 --- a/src/invidious/helpers/errors.cr +++ b/src/invidious/helpers/errors.cr @@ -46,7 +46,7 @@ def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exce TEXT - issue_template += github_details("Backtrace", HTML.escape(exception.inspect_with_backtrace)) + issue_template += github_details("Backtrace", exception.inspect_with_backtrace) # URLs for the error message below url_faq = "https://github.com/iv-org/documentation/blob/master/docs/faq.md" From 7f2176d7fcc8e65b5eab97e991b8b853a952a0a0 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 1 May 2022 17:00:56 +0200 Subject: [PATCH 42/48] Add 'targetDurationSec' and 'maxDvrDurationSec' to videos API --- src/invidious/videos.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 27c2b6d12..8a6a0f1ac 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -413,6 +413,10 @@ struct Video end end + # Livestream chunk infos + json.field "targetDurationSec", fmt["targetDurationSec"].as_i if fmt.has_key?("targetDurationSec") + json.field "maxDvrDurationSec", fmt["maxDvrDurationSec"].as_i if fmt.has_key?("maxDvrDurationSec") + # Audio-related data json.field "audioQuality", fmt["audioQuality"] if fmt.has_key?("audioQuality") json.field "audioSampleRate", fmt["audioSampleRate"].as_s.to_i if fmt.has_key?("audioSampleRate") From f5fb4c6c64da58415dafba34087fa7dd9c11509a Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 1 May 2022 21:10:43 +0200 Subject: [PATCH 43/48] Apply 2859.diff --- src/invidious/channels/about.cr | 7 ++- src/invidious/comments.cr | 8 +++- src/invidious/helpers/serialized_yt_data.cr | 7 ++- src/invidious/routes/feeds.cr | 1 + src/invidious/videos.cr | 14 ++++++ src/invidious/views/channel.ecr | 2 +- src/invidious/views/community.ecr | 2 +- src/invidious/views/components/item.ecr | 6 +-- src/invidious/views/playlists.ecr | 2 +- src/invidious/views/watch.ecr | 6 +-- src/invidious/yt_backend/extractors.cr | 48 +++++++++++++++------ 11 files changed, 77 insertions(+), 26 deletions(-) diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr index 4f82a0f1f..d48fd1fb9 100644 --- a/src/invidious/channels/about.cr +++ b/src/invidious/channels/about.cr @@ -12,7 +12,8 @@ record AboutChannel, joined : Time, is_family_friendly : Bool, allowed_regions : Array(String), - tabs : Array(String) + tabs : Array(String), + verified : Bool record AboutRelatedChannel, ucid : String, @@ -70,6 +71,9 @@ def get_about_info(ucid, locale) : AboutChannel # if banner.includes? "channels/c4/default_banner" # banner = nil # end + # author_verified_badges = initdata["header"]?.try &.["c4TabbedHeaderRenderer"]?.try &.["badges"]? + author_verified_badge = initdata["header"].dig?("c4TabbedHeaderRenderer", "badges", 0, "metadataBadgeRenderer", "tooltip") + author_verified = (author_verified_badge && author_verified_badge == "Verified") description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" description_html = HTML.escape(description) @@ -128,6 +132,7 @@ def get_about_info(ucid, locale) : AboutChannel is_family_friendly: is_family_friendly, allowed_regions: allowed_regions, tabs: tabs, + verified: author_verified || false, ) end diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index c6e7fd174..3ae49aa6d 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -146,6 +146,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" author = node_comment["authorText"]?.try &.["simpleText"]? || "" + json.field "verified", (node_comment["authorCommentBadge"]? != nil) + json.field "author", author json.field "authorThumbnails" do json.array do @@ -329,7 +331,11 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) - + if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool + author_name += " " + elsif child["verified"]?.try &.as_bool + author_name += " " + end html << <<-END_HTML
diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index bfbc237ce..3918bd130 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -12,6 +12,7 @@ struct SearchVideo property live_now : Bool property premium : Bool property premiere_timestamp : Time? + property author_verified : Bool def to_xml(auto_generated, query_params, xml : XML::Builder) query_params["v"] = self.id @@ -129,6 +130,7 @@ struct SearchPlaylist property video_count : Int32 property videos : Array(SearchPlaylistVideo) property thumbnail : String? + property author_verified : Bool def to_json(locale : String?, json : JSON::Builder) json.object do @@ -141,6 +143,8 @@ struct SearchPlaylist json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" + json.field "authorVerified", self.author_verified + json.field "videoCount", self.video_count json.field "videos" do json.array do @@ -182,6 +186,7 @@ struct SearchChannel property video_count : Int32 property description_html : String property auto_generated : Bool + property author_verified : Bool def to_json(locale : String?, json : JSON::Builder) json.object do @@ -189,7 +194,7 @@ struct SearchChannel json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" - + json.field "authorVerified", self.author_verified json.field "authorThumbnails" do json.array do qualities = {32, 48, 76, 100, 176, 512} diff --git a/src/invidious/routes/feeds.cr b/src/invidious/routes/feeds.cr index f7f7b426a..b5b583996 100644 --- a/src/invidious/routes/feeds.cr +++ b/src/invidious/routes/feeds.cr @@ -182,6 +182,7 @@ module Invidious::Routes::Feeds paid: false, premium: false, premiere_timestamp: nil, + author_verified: false, # ¯\_(ツ)_/¯ }) end diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 8a6a0f1ac..b16955b10 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -613,6 +613,10 @@ struct Video info["authorThumbnail"]?.try &.as_s || "" end + def author_verified : Bool + info["authorVerified"].try &.as_bool || false + end + def sub_count_text : String info["subCountText"]?.try &.as_s || "-" end @@ -864,6 +868,12 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? .try &.dig?("runs", 0) author = channel_info.try &.dig?("text") + author_verified_badge = related["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + + author_verified = (author_verified_badge && author_verified_badge.size > 0).to_s + ucid = channel_info.try { |ci| HelperExtractors.get_browse_id(ci) } # "4,088,033 views", only available on compact renderer @@ -887,6 +897,7 @@ def parse_related_video(related : JSON::Any) : Hash(String, JSON::Any)? "length_seconds" => JSON::Any.new(length || "0"), "view_count" => JSON::Any.new(view_count || "0"), "short_view_count" => JSON::Any.new(short_view_count || "0"), + "author_verified" => JSON::Any.new(author_verified), } end @@ -1081,6 +1092,9 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") + author_verified_badge = author_info.try &.dig?("badges", 0, "metadataBadgeRenderer", "tooltip") + params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge == "Verified")) + params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 40b553a9c..92f81ee49 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -20,7 +20,7 @@
- <%= author %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index f0add06bf..3bc29e552 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -19,7 +19,7 @@
- <%= author %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index ce7af783f..fb7ad1dc7 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -8,7 +8,7 @@ "/> <% end %> -

<%= HTML.escape(item.author) %>

+

<%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %> <% end %>

<%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %>

<% if !item.auto_generated %>

<%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %>

<% end %> @@ -30,7 +30,7 @@

<%= HTML.escape(item.title) %>

-

<%= HTML.escape(item.author) %>

+

<%= HTML.escape(item.author) %><% if !item.is_a?(InvidiousPlaylist) && !item.author_verified.nil? && item.author_verified %> <% end %>

<% when MixVideo %> @@ -142,7 +142,7 @@
<% endpoint_params = "?v=#{item.id}" %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index 12dba088f..c8718e7b7 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -19,7 +19,7 @@
- <%= author %> + <%= author %><% if !channel.verified.nil? && channel.verified %> <% end %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 2e493f4cc..8b6eb903a 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -207,7 +207,7 @@ we're going to need to do it here in order to allow for translations. <% if !video.author_thumbnail.empty? %> <% end %> - <%= author %> + <%= author %><% if !video.author_verified.nil? && video.author_verified %> <% end %>
@@ -281,9 +281,9 @@ we're going to need to do it here in order to allow for translations.
<% if rv["ucid"]? %> - "><%= rv["author"]? %> + "><%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% else %> - <%= rv["author"]? %> + <%= rv["author"]? %><% if rv["author_verified"]? == "true" %> <% end %> <% end %>
diff --git a/src/invidious/yt_backend/extractors.cr b/src/invidious/yt_backend/extractors.cr index ce39bc284..4657bb1d9 100644 --- a/src/invidious/yt_backend/extractors.cr +++ b/src/invidious/yt_backend/extractors.cr @@ -102,7 +102,11 @@ private module Parsers premium = false premiere_timestamp = item_contents.dig?("upcomingEventData", "startTime").try { |t| Time.unix(t.as_s.to_i64) } + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) item_contents["badges"]?.try &.as_a.each do |badge| b = badge["metadataBadgeRenderer"] case b["label"].as_s @@ -129,6 +133,7 @@ private module Parsers live_now: live_now, premium: premium, premiere_timestamp: premiere_timestamp, + author_verified: author_verified || false, }) end @@ -156,7 +161,11 @@ private module Parsers private def self.parse(item_contents, author_fallback) author = extract_text(item_contents["title"]) || author_fallback.name author_id = item_contents["channelId"]?.try &.as_s || author_fallback.id + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) author_thumbnail = HelperExtractors.get_thumbnails(item_contents) # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. # Always simpleText @@ -179,6 +188,7 @@ private module Parsers video_count: video_count, description_html: description_html, auto_generated: auto_generated, + author_verified: author_verified || false, }) end @@ -206,18 +216,23 @@ private module Parsers private def self.parse(item_contents, author_fallback) title = extract_text(item_contents["title"]) || "" plid = item_contents["playlistId"]?.try &.as_s || "" + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) video_count = HelperExtractors.get_video_count(item_contents) playlist_thumbnail = HelperExtractors.get_thumbnails(item_contents) SearchPlaylist.new({ - title: title, - id: plid, - author: author_fallback.name, - ucid: author_fallback.id, - video_count: video_count, - videos: [] of SearchPlaylistVideo, - thumbnail: playlist_thumbnail, + title: title, + id: plid, + author: author_fallback.name, + ucid: author_fallback.id, + video_count: video_count, + videos: [] of SearchPlaylistVideo, + thumbnail: playlist_thumbnail, + author_verified: author_verified || false, }) end @@ -251,7 +266,11 @@ private module Parsers author_info = item_contents.dig?("shortBylineText", "runs", 0) author = author_info.try &.["text"].as_s || author_fallback.name author_id = author_info.try { |x| HelperExtractors.get_browse_id(x) } || author_fallback.id + author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| + badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") + end + author_verified = (author_verified_badge && author_verified_badge.size > 0) videos = item_contents["videos"]?.try &.as_a.map do |v| v = v["childVideoRenderer"] v_title = v.dig?("title", "simpleText").try &.as_s || "" @@ -267,13 +286,14 @@ private module Parsers # TODO: item_contents["publishedTimeText"]? SearchPlaylist.new({ - title: title, - id: plid, - author: author, - ucid: author_id, - video_count: video_count, - videos: videos, - thumbnail: playlist_thumbnail, + title: title, + id: plid, + author: author, + ucid: author_id, + video_count: video_count, + videos: videos, + thumbnail: playlist_thumbnail, + author_verified: author_verified || false, }) end From b84ce6a5568429ffa30d993a8cd0410cfb72449b Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 1 May 2022 21:11:12 +0200 Subject: [PATCH 44/48] Fix "cast from Nil to Bool failed" --- src/invidious/videos.cr | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index b16955b10..7c1f68a86 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -614,7 +614,7 @@ struct Video end def author_verified : Bool - info["authorVerified"].try &.as_bool || false + info["authorVerified"]?.try &.as_bool || false end def sub_count_text : String @@ -1093,7 +1093,8 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") author_verified_badge = author_info.try &.dig?("badges", 0, "metadataBadgeRenderer", "tooltip") - params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge == "Verified")) + author_verified = (!author_verified_badge.nil? && author_verified_badge == "Verified") + params["authorVerified"] = JSON::Any.new(author_verified) params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") From 9c00140464b5f3461357a6b574bdddd7a926f7f8 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 2 May 2022 19:28:57 +0200 Subject: [PATCH 45/48] Update Hindi translation Add Hindi translation Co-authored-by: Creeper Co-authored-by: Hosted Weblate --- locales/hi.json | 474 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) create mode 100644 locales/hi.json diff --git a/locales/hi.json b/locales/hi.json new file mode 100644 index 000000000..0fc35b255 --- /dev/null +++ b/locales/hi.json @@ -0,0 +1,474 @@ +{ + "last": "आखिरी", + "Yes": "हाँ", + "No": "नहीं", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "OPML के रूप में सदस्यताएँ निर्यात करें (NewPipe और FreeTube के लिए)", + "Log in/register": "लॉग-इन/पंजीकृत करें", + "Log in with Google": "Google के साथ लॉग-इन करें", + "preferences_autoplay_label": "अपने आप चलाने की सुविधा: ", + "preferences_dark_mode_label": "थीम: ", + "preferences_default_home_label": "डिफ़ॉल्ट मुखपृष्ठ: ", + "Could not fetch comments": "टिप्पणियाँ प्राप्त न की जा सकीं", + "comments_points_count": "{{count}} पॉइंट", + "comments_points_count_plural": "{{count}} पॉइंट्स", + "Subscription manager": "सदस्यता प्रबंधन", + "License: ": "लाइसेंस: ", + "Wilson score: ": "Wilson स्कोर: ", + "Wrong answer": "गलत जवाब", + "Erroneous CAPTCHA": "गलत CAPTCHA", + "Please log in": "कृपया लॉग-इन करें", + "Bosnian": "बोस्नियाई", + "Bulgarian": "बुल्गारियाई", + "Burmese": "बर्मी", + "Chinese (Traditional)": "चीनी (पारंपरिक)", + "Kurdish": "कुर्द", + "Punjabi": "पंजाबी", + "Sinhala": "सिंहली", + "Slovak": "स्लोवाक", + "generic_count_days": "{{count}} दिन", + "generic_count_days_plural": "{{count}} दिन", + "generic_count_hours": "{{count}} घंटे", + "generic_count_hours_plural": "{{count}} घंटे", + "generic_count_minutes": "{{count}} मिनट", + "generic_count_minutes_plural": "{{count}} मिनट", + "generic_count_seconds": "{{count}} सेकंड", + "generic_count_seconds_plural": "{{count}} सेकंड", + "generic_playlists_count": "{{count}} प्लेलिस्ट", + "generic_playlists_count_plural": "{{count}} प्लेलिस्ट्स", + "crash_page_report_issue": "अगर इनमें से कुछ भी काम नहीं करता, कृपया GitHub पर एक नया मुद्दा खोल दें (अंग्रेज़ी में) और अपने संदेश में यह टेक्स्ट दर्ज करें (इसे अनुवादित न करें!):", + "generic_views_count": "{{count}} बार देखा गया", + "generic_views_count_plural": "{{count}} बार देखा गया", + "generic_videos_count": "{{count}} वीडियो", + "generic_videos_count_plural": "{{count}} वीडियो", + "generic_subscribers_count": "{{count}} सदस्य", + "generic_subscribers_count_plural": "{{count}} सदस्य", + "generic_subscriptions_count": "{{count}} सदस्यता", + "generic_subscriptions_count_plural": "{{count}} सदस्यताएँ", + "LIVE": "लाइव", + "Shared `x` ago": "`x` पहले बाँटा गया", + "Unsubscribe": "सदस्यता छोड़ें", + "Subscribe": "सदस्यता लें", + "View channel on YouTube": "चैनल YouTube पर देखें", + "View playlist on YouTube": "प्लेलिस्ट YouTube पर देखें", + "newest": "सबसे नया", + "oldest": "सबसे पुराना", + "popular": "सर्वाधिक लोकप्रिय", + "Next page": "अगला पृष्ठ", + "Previous page": "पिछला पृष्ठ", + "Clear watch history?": "देखने का इतिहास मिटाएँ?", + "New password": "नया पासवर्ड", + "New passwords must match": "पासवर्ड्स को मेल खाना होगा", + "Cannot change password for Google accounts": "Google खातों के लिए पासवर्ड नहीं बदल सकते", + "Authorize token?": "टोकन को प्रमाणित करें?", + "Authorize token for `x`?": "`x` के लिए टोकन को प्रमाणित करें?", + "Import and Export Data": "डेटा को आयात और निर्यात करें", + "Import": "आयात करें", + "Import Invidious data": "Invidious JSON डेटा आयात करें", + "Import YouTube subscriptions": "YouTube/OPML सदस्यताएँ आयात करें", + "Import FreeTube subscriptions (.db)": "FreeTube सदस्यताएँ आयात करें (.db)", + "Import NewPipe subscriptions (.json)": "NewPipe सदस्यताएँ आयात करें (.json)", + "Import NewPipe data (.zip)": "NewPipe डेटा आयात करें (.zip)", + "Export": "निर्यात करें", + "Export subscriptions as OPML": "OPML के रूप में सदस्यताएँ निर्यात करें", + "Export data as JSON": "Invidious डेटा को JSON के रूप में निर्यात करें", + "Delete account?": "खाता हटाएँ?", + "History": "देखे गए वीडियो", + "An alternative front-end to YouTube": "YouTube का एक वैकल्पिक फ्रंट-एंड", + "JavaScript license information": "जावास्क्रिप्ट लाइसेंस की जानकारी", + "source": "स्रोत", + "Log in": "लॉग-इन करें", + "User ID": "सदस्य ID", + "Password": "पासवर्ड", + "Register": "पंजीकृत करें", + "E-mail": "ईमेल", + "Google verification code": "Google प्रमाणीकरण कोड", + "Time (h:mm:ss):": "समय (घं:मिमि:सेसे):", + "Text CAPTCHA": "टेक्स्ट CAPTCHA", + "Image CAPTCHA": "चित्र CAPTCHA", + "Sign In": "साइन इन करें", + "Preferences": "प्राथमिकताएँ", + "preferences_category_player": "प्लेयर की प्राथमिकताएँ", + "preferences_video_loop_label": "हमेशा लूप करें: ", + "preferences_continue_label": "डिफ़ॉल्ट से अगला चलाएँ: ", + "preferences_continue_autoplay_label": "अगला वीडियो अपने आप चलाएँ: ", + "preferences_listen_label": "डिफ़ॉल्ट से सुनें: ", + "preferences_local_label": "प्रॉक्सी वीडियो: ", + "preferences_watch_history_label": "देखने का इतिहास सक्षम करें: ", + "preferences_speed_label": "वीडियो चलाने की डिफ़ॉल्ट रफ़्तार: ", + "preferences_quality_label": "वीडियो की प्राथमिक क्वालिटी: ", + "preferences_quality_option_dash": "DASH (अनुकूली गुणवत्ता)", + "preferences_quality_option_hd720": "HD720", + "preferences_quality_option_medium": "मध्यम", + "preferences_quality_option_small": "छोटा", + "preferences_quality_dash_label": "प्राथमिक DASH वीडियो क्वालिटी: ", + "preferences_quality_dash_option_720p": "720p", + "preferences_quality_dash_option_auto": "अपने-आप", + "preferences_quality_dash_option_best": "सबसे अच्छा", + "preferences_quality_dash_option_worst": "सबसे खराब", + "preferences_quality_dash_option_4320p": "4320p", + "preferences_quality_dash_option_2160p": "2160p", + "preferences_quality_dash_option_1440p": "1440p", + "preferences_quality_dash_option_1080p": "1080p", + "preferences_quality_dash_option_480p": "480p", + "preferences_quality_dash_option_360p": "360p", + "preferences_quality_dash_option_240p": "240p", + "preferences_quality_dash_option_144p": "144p", + "preferences_comments_label": "डिफ़ॉल्ट टिप्पणियाँ: ", + "preferences_volume_label": "प्लेयर का वॉल्यूम: ", + "youtube": "YouTube", + "reddit": "Reddit", + "invidious": "Invidious", + "preferences_captions_label": "डिफ़ॉल्ट कैप्शन: ", + "Fallback captions: ": "वैकल्पिक कैप्शन: ", + "preferences_related_videos_label": "संबंधित वीडियो दिखाएँ: ", + "preferences_annotations_label": "डिफ़ॉल्ट से टिप्पणियाँ दिखाएँ: ", + "preferences_extend_desc_label": "अपने आप वीडियो के विवरण का विस्तार करें: ", + "preferences_vr_mode_label": "उत्तरदायी 360 डिग्री वीडियो (WebGL की ज़रूरत है): ", + "preferences_category_visual": "यथादृश्य प्राथमिकताएँ", + "preferences_region_label": "सामग्री का राष्ट्र: ", + "preferences_player_style_label": "प्लेयर का स्टाइल: ", + "Dark mode: ": "डार्क मोड: ", + "dark": "डार्क", + "light": "लाइट", + "preferences_thin_mode_label": "हल्का मोड: ", + "preferences_category_misc": "विविध प्राथमिकताएँ", + "preferences_automatic_instance_redirect_label": "अपने आप अनुप्रेषित करें (redirect.invidious.io पर फ़ॉलबैक करें): ", + "preferences_category_subscription": "सदस्यताओं की प्राथमिकताएँ", + "preferences_annotations_subscribed_label": "सदस्यता लिए गए चैनलों पर डिफ़ॉल्ट से टिप्पणियाँ दिखाएँ? ", + "Redirect homepage to feed: ": "फ़ीड पर मुखपृष्ठ को अनुप्रेषित करें: ", + "preferences_max_results_label": "फ़ीड में दिखाए जाने वाले वीडियों की संख्या: ", + "preferences_sort_label": "वीडियों को इस मानदंड पर छाँटें: ", + "published": "प्रकाशित", + "published - reverse": "प्रकाशित - उल्टा", + "Only show latest video from channel: ": "चैनल से सिर्फ नवीनतम वीडियो ही दिखाएँ: ", + "alphabetically": "वर्णक्रमानुसार", + "Only show latest unwatched video from channel: ": "चैनल से सिर्फ न देखा गया नवीनतम वीडियो ही दिखाएँ: ", + "alphabetically - reverse": "वर्णक्रमानुसार - उल्टा", + "channel name": "चैनल का नाम", + "channel name - reverse": "चैनल का नाम - उल्टा", + "preferences_unseen_only_label": "सिर्फ न देखे गए वीडियो ही दिखाएँ: ", + "preferences_notifications_only_label": "सिर्फ सूचनाएँ दिखाएँ (अगर हो तो): ", + "Enable web notifications": "वेब सूचनाएँ सक्षम करें", + "`x` uploaded a video": "`x` ने वीडियो अपलोड किया", + "`x` is live": "`x` लाइव हैं", + "preferences_category_data": "डेटा की प्राथमिकताएँ", + "Clear watch history": "देखने का इतिहास साफ़ करें", + "Import/export data": "डेटा को आयात/निर्यात करें", + "Change password": "पासवर्ड बदलें", + "Manage subscriptions": "सदस्यताएँ प्रबंधित करें", + "Manage tokens": "टोकन प्रबंधित करें", + "Watch history": "देखने का इतिहास", + "Delete account": "खाता हटाएँ", + "preferences_category_admin": "प्रबंधक प्राथमिकताएँ", + "preferences_feed_menu_label": "फ़ीड मेन्यू: ", + "preferences_show_nick_label": "ऊपर उपनाम दिखाएँ: ", + "Top enabled: ": "ऊपर का हिस्सा सक्षम है: ", + "CAPTCHA enabled: ": "CAPTCHA सक्षम है: ", + "Login enabled: ": "लॉग-इन सक्षम है: ", + "Registration enabled: ": "पंजीकरण सक्षम है: ", + "Report statistics: ": "सांख्यिकी रिपोर्ट करें: ", + "Released under the AGPLv3 on Github.": "GitHub पर AGPLv3 के अंतर्गत प्रकाशित।", + "Save preferences": "प्राथमिकताएँ सहेजें", + "Token manager": "टोकन प्रबंधन", + "Token": "टोकन", + "tokens_count": "{{count}} टोकन", + "tokens_count_plural": "{{count}} टोकन", + "Import/export": "आयात/निर्यात करें", + "unsubscribe": "सदस्यता छोड़ें", + "revoke": "हटाएँ", + "Subscriptions": "सदस्यताएँ", + "subscriptions_unseen_notifs_count": "{{count}} अपठित सूचना", + "subscriptions_unseen_notifs_count_plural": "{{count}} अपठित सूचना", + "search": "खोजें", + "Log out": "लॉग-आउट करें", + "Source available here.": "स्रोत यहाँ उपलब्ध है।", + "View JavaScript license information.": "जावास्क्रिप्ट लाइसेंस की जानकारी देखें।", + "View privacy policy.": "निजता नीति देखें।", + "Trending": "रुझान में", + "Public": "सार्वजनिक", + "Unlisted": "सबके लिए उपलब्ध नहीं", + "Private": "निजी", + "View all playlists": "सभी प्लेलिस्ट देखें", + "Create playlist": "प्लेलिस्ट बनाएँ", + "Updated `x` ago": "`x` पहले अपडेट किया गया", + "Delete playlist `x`?": "प्लेलिस्ट `x` हटाएँ?", + "Delete playlist": "प्लेलिस्ट हटाएँ", + "Title": "शीर्षक", + "Playlist privacy": "प्लेलिस्ट की निजता", + "Editing playlist `x`": "प्लेलिस्ट `x` को संपादित किया जा रहा है", + "Show more": "अधिक देखें", + "Show less": "कम देखें", + "Watch on YouTube": "YouTube पर देखें", + "Switch Invidious Instance": "Invidious उदाहरण बदलें", + "search_message_no_results": "कोई परिणाम नहीं मिला।", + "search_message_change_filters_or_query": "अपने खोज क्वेरी को और चौड़ा करें और/या फ़िल्टर बदलें।", + "search_message_use_another_instance": " आप दूसरे उदाहरण पर भी खोज सकते हैं।", + "Hide annotations": "टिप्पणियाँ छिपाएँ", + "Show annotations": "टिप्पणियाँ दिखाएँ", + "Genre: ": "श्रेणी: ", + "Family friendly? ": "परिवार के लिए ठीक है? ", + "Engagement: ": "सगाई: ", + "Whitelisted regions: ": "स्वीकृत क्षेत्र: ", + "Blacklisted regions: ": "अस्वीकृत क्षेत्र: ", + "Shared `x`": "`x` बाँटा गया", + "Premieres in `x`": "`x` बाद प्रीमियर होगा", + "Premieres `x`": "`x` को प्रीमिर होगा", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "नमस्कार! ऐसा लगता है कि आपका जावास्क्रिप्ट अक्षम है। टिप्पणियाँ देखने के लिए यहाँ क्लिक करें, लेकिन याद रखें कि इन्हें लोड होने में थोड़ा ज़्यादा समय लग सकता है।", + "View YouTube comments": "YouTube टिप्पणियाँ देखें", + "View more comments on Reddit": "Reddit पर अधिक टिप्पणियाँ देखें", + "View `x` comments": { + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` टिप्पणी देखें", + "": "`x` टिप्पणियाँ देखें" + }, + "View Reddit comments": "Reddit पर टिप्पणियाँ", + "Hide replies": "जवाब छिपाएँ", + "Show replies": "जवाब दिखाएँ", + "Incorrect password": "गलत पासवर्ड", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "लॉग-इन नहीं किया जा सका, सुनिश्चित करें कि दो-कारक प्रमाणीकरण (Authenticator या SMS) सक्षम है।", + "Invalid TFA code": "अमान्य TFA कोड", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "लॉग-इन नाकाम रहा। ऐसा इसलिए हो सकता है कि दो-कारक प्रमाणीकरण आपके खाते पर सक्षम नहीं है।", + "Quota exceeded, try again in a few hours": "कोटा पार हो चुका है, कृपया कुछ घंटों में फिर कोशिश करें", + "CAPTCHA is a required field": "CAPTCHA एक ज़रूरी फ़ील्ड है", + "User ID is a required field": "सदस्य ID एक ज़रूरी फ़ील्ड है", + "Password is a required field": "पासवर्ड एक ज़रूरी फ़ील्ड है", + "Wrong username or password": "गलत सदस्यनाम या पासवर्ड", + "Please sign in using 'Log in with Google'": "कृपया 'Google के साथ लॉग-इन करें' के साथ साइन-इन करें", + "Password cannot be empty": "पासवर्ड खाली नहीं हो सकता", + "Password cannot be longer than 55 characters": "पासवर्ड में अधिकतम 55 अक्षर हो सकते हैं", + "Invidious Private Feed for `x`": "`x` के लिए Invidious निजी फ़ीड", + "channel:`x`": "चैनल:`x`", + "Deleted or invalid channel": "हटाया गया या अमान्य चैनल", + "This channel does not exist.": "यह चैनल मौजूद नहीं है।", + "Could not get channel info.": "चैनल की जानकारी प्राप्त न की जा सकी।", + "comments_view_x_replies": "{{count}} टिप्पणी देखें", + "comments_view_x_replies_plural": "{{count}} टिप्पणियाँ देखें", + "`x` ago": "`x` पहले", + "Load more": "अधिक लोड करें", + "Could not create mix.": "मिक्स न बनाया जा सका।", + "Empty playlist": "खाली प्लेलिस्ट", + "Not a playlist.": "यह प्लेलिस्ट नहीं है।", + "Playlist does not exist.": "प्लेलिस्ट मौजूद नहीं है।", + "Could not pull trending pages.": "रुझान के पृष्ठ प्राप्त न किए जा सके।", + "Hidden field \"challenge\" is a required field": "छिपाया गया फ़ील्ड \"चुनौती\" एक आवश्यक फ़ील्ड है", + "Hidden field \"token\" is a required field": "छिपाया गया फ़ील्ड \"टोकन\" एक आवश्यक फ़ील्ड है", + "Erroneous challenge": "त्रुटिपूर्ण चुनौती", + "Erroneous token": "त्रुटिपूर्ण टोकन", + "No such user": "यह सदस्य मौजूद नहीं हैं", + "Token is expired, please try again": "टोकन की समय-सीमा समाप्त हो चुकी है, कृपया दोबारा कोशिश करें", + "English": "अंग्रेज़ी", + "English (United Kingdom)": "अंग्रेज़ी (यूनाइटेड किंग्डम)", + "English (United States)": "अंग्रेज़ी (संयुक्त राष्ट्र)", + "English (auto-generated)": "अंग्रेज़ी (अपने-आप जनरेट हुआ)", + "Afrikaans": "अफ़्रीकी", + "Albanian": "अल्बानियाई", + "Amharic": "अम्हेरी", + "Arabic": "अरबी", + "Armenian": "आर्मेनियाई", + "Belarusian": "बेलारूसी", + "Azerbaijani": "अज़रबैजानी", + "Bangla": "बंगाली", + "Basque": "बास्क", + "Cantonese (Hong Kong)": "कैंटोनीज़ (हाँग काँग)", + "Catalan": "कातालान", + "Cebuano": "सेबुआनो", + "Chinese": "चीनी", + "Chinese (China)": "चीनी (चीन)", + "Chinese (Hong Kong)": "चीनी (हाँग काँग)", + "Chinese (Simplified)": "चीनी (सरलीकृत)", + "Chinese (Taiwan)": "चीनी (ताइवान)", + "Corsican": "कोर्सिकन", + "Croatian": "क्रोएशियाई", + "Czech": "चेक", + "Danish": "डेनिश", + "Dutch": "डच", + "Dutch (auto-generated)": "डच (अपने-आप जनरेट हुआ)", + "Esperanto": "एस्पेरांतो", + "Estonian": "एस्टोनियाई", + "Filipino": "फ़िलिपीनो", + "Finnish": "फ़िनिश", + "French": "फ़्रेंच", + "French (auto-generated)": "फ़्रेंच (अपने-आप जनरेट हुआ)", + "Galician": "गैलिशियन", + "Georgian": "जॉर्जियाई", + "German": "जर्मन", + "German (auto-generated)": "जर्मन (अपने-आप जनरेट हुआ)", + "Greek": "यूनानी", + "Gujarati": "गुजराती", + "Haitian Creole": "हैती क्रियोल", + "Hausa": "हौसा", + "Hawaiian": "हवाई", + "Hebrew": "हीब्रू", + "Hindi": "हिन्दी", + "Hmong": "हमोंग", + "Hungarian": "हंगेरी", + "Icelandic": "आइसलैंडिक", + "Igbo": "इग्बो", + "Indonesian": "इंडोनेशियाई", + "Indonesian (auto-generated)": "इंडोनेशियाई (अपने-आप जनरेट हुआ)", + "Interlingue": "इंटरलिंगुआ", + "Irish": "आयरिश", + "Italian": "इतालवी", + "Italian (auto-generated)": "इतालवी (अपने-आप जनरेट हुआ)", + "Japanese": "जापानी", + "Japanese (auto-generated)": "जापानी (अपने-आप जनरेट हुआ)", + "Javanese": "जावानीज़", + "Kannada": "कन्नड़", + "Kazakh": "कज़ाख़", + "Khmer": "खमेर", + "Korean": "कोरियाई", + "Korean (auto-generated)": "कोरियाई (अपने-आप जनरेट हुआ)", + "Kyrgyz": "किर्गीज़", + "Lao": "लाओ", + "Latin": "लैटिन", + "Latvian": "लातवियाई", + "Lithuanian": "लिथुएनियाई", + "Luxembourgish": "लग्ज़मबर्गी", + "Macedonian": "मकादूनियाई", + "Malagasy": "मालागासी", + "Malay": "मलय", + "Malayalam": "मलयालम", + "Maltese": "माल्टीज़", + "Maori": "माओरी", + "Marathi": "मराठी", + "Mongolian": "मंगोलियाई", + "Nepali": "नेपाली", + "Norwegian Bokmål": "नॉर्वेजियाई", + "Nyanja": "न्यानजा", + "Pashto": "पश्तो", + "Persian": "फ़ारसी", + "Polish": "पोलिश", + "Portuguese": "पुर्तगाली", + "Portuguese (auto-generated)": "पुर्तगाली (अपने-आप जनरेट हुआ)", + "Portuguese (Brazil)": "पुर्तगाली (ब्राज़ील)", + "Romanian": "रोमेनियाई", + "Russian": "रूसी", + "Russian (auto-generated)": "रूसी (अपने-आप जनरेट हुआ)", + "Samoan": "सामोन", + "Scottish Gaelic": "स्कॉटिश गाएलिक", + "Serbian": "सर्बियाई", + "Shona": "शोणा", + "Sindhi": "सिंधी", + "Slovenian": "स्लोवेनियाई", + "Somali": "सोमाली", + "Southern Sotho": "दक्षिणी सोथो", + "Spanish": "स्पेनी", + "Spanish (auto-generated)": "स्पेनी (अपने-आप जनरेट हुआ)", + "Spanish (Latin America)": "स्पेनी (लातिन अमेरिकी)", + "Spanish (Mexico)": "स्पेनी (मेक्सिको)", + "Spanish (Spain)": "स्पेनी (स्पेन)", + "Sundanese": "सुंडानी", + "Swahili": "स्वाहिली", + "Swedish": "स्वीडिश", + "Tajik": "ताजीक", + "Tamil": "तमिल", + "Telugu": "तेलुगु", + "Thai": "थाई", + "Turkish": "तुर्की", + "Turkish (auto-generated)": "तुर्की (अपने-आप जनरेट हुआ)", + "Ukrainian": "यूक्रेनी", + "Urdu": "उर्दू", + "Uzbek": "उज़्बेक", + "Vietnamese": "वियतनामी", + "Vietnamese (auto-generated)": "वियतनामी (अपने-आप जनरेट हुआ)", + "Welsh": "Welsh", + "Western Frisian": "पश्चिमी फ़्रिसियाई", + "Xhosa": "खोसा", + "Yiddish": "यहूदी", + "generic_count_years": "{{count}} वर्ष", + "generic_count_years_plural": "{{count}} वर्ष", + "Yoruba": "योरुबा", + "generic_count_months": "{{count}} महीने", + "generic_count_months_plural": "{{count}} महीने", + "Zulu": "ज़ूलू", + "generic_count_weeks": "{{count}} हफ़्ते", + "generic_count_weeks_plural": "{{count}} हफ़्ते", + "Fallback comments: ": "फ़ॉलबैक टिप्पणियाँ: ", + "Popular": "प्रसिद्ध", + "Search": "खोजें", + "Top": "ऊपर", + "About": "जानकारी", + "Rating: ": "रेटिंग: ", + "preferences_locale_label": "भाषा: ", + "View as playlist": "प्लेलिस्ट के रूप में देखें", + "Default": "डिफ़ॉल्ट", + "Download": "डाउनलोड करें", + "Download as: ": "इस रूप में डाउनलोड करें: ", + "%A %B %-d, %Y": "%A %B %-d, %Y", + "Music": "संगीत", + "Gaming": "गेमिंग", + "News": "समाचार", + "Movies": "फ़िल्में", + "(edited)": "(संपादित)", + "YouTube comment permalink": "YouTube पर टिप्पणी की स्थायी कड़ी", + "permalink": "स्थायी कड़ी", + "Videos": "वीडियो", + "`x` marked it with a ❤": "`x` ने इसे एक ❤ से चिह्नित किया", + "Audio mode": "ऑडियो मोड", + "Playlists": "प्लेलिस्ट्स", + "Video mode": "वीडियो मोड", + "Community": "समुदाय", + "search_filters_title": "फ़िल्टर", + "search_filters_date_label": "अपलोड करने का समय", + "search_filters_date_option_none": "कोई भी समय", + "search_filters_date_option_week": "इस हफ़्ते", + "search_filters_date_option_month": "इस महीने", + "search_filters_date_option_hour": "पिछला घंटा", + "search_filters_date_option_today": "आज", + "search_filters_date_option_year": "इस साल", + "search_filters_type_label": "प्रकार", + "search_filters_type_option_all": "कोई भी प्रकार", + "search_filters_type_option_video": "वीडियो", + "search_filters_type_option_channel": "चैनल", + "search_filters_sort_option_relevance": "प्रासंगिकता", + "search_filters_type_option_playlist": "प्लेलिस्ट", + "search_filters_type_option_movie": "फ़िल्म", + "search_filters_type_option_show": "शो", + "search_filters_duration_label": "अवधि", + "search_filters_duration_option_none": "कोई भी अवधि", + "search_filters_duration_option_short": "4 मिनट से कम", + "search_filters_duration_option_medium": "4 से 20 मिनट तक", + "search_filters_duration_option_long": "20 मिनट से ज़्यादा", + "search_filters_features_label": "सुविधाएँ", + "search_filters_features_option_live": "लाइव", + "search_filters_sort_option_rating": "रेटिंग", + "search_filters_features_option_four_k": "4K", + "search_filters_features_option_hd": "HD", + "search_filters_features_option_subtitles": "उपशीर्षक/कैप्शन", + "search_filters_features_option_c_commons": "क्रिएटिव कॉमन्स", + "search_filters_features_option_three_sixty": "360°", + "search_filters_features_option_vr180": "VR180", + "search_filters_features_option_three_d": "3D", + "search_filters_features_option_hdr": "HDR", + "search_filters_features_option_location": "जगह", + "search_filters_features_option_purchased": "खरीदा गया", + "search_filters_sort_label": "इस क्रम से लगाएँ", + "search_filters_sort_option_date": "अपलोड की ताऱीख", + "search_filters_sort_option_views": "देखे जाने की संख्या", + "search_filters_apply_button": "चयनित फ़िल्टर लागू करें", + "footer_documentation": "प्रलेख", + "footer_source_code": "स्रोत कोड", + "footer_original_source_code": "मूल स्रोत कोड", + "footer_modfied_source_code": "बदला गया स्रोत कोड", + "Current version: ": "वर्तमान संस्करण: ", + "next_steps_error_message": "इसके बाद आपके ये आज़माने चाहिए: ", + "next_steps_error_message_refresh": "साफ़ करें", + "next_steps_error_message_go_to_youtube": "YouTube पर जाएँ", + "footer_donate_page": "दान करें", + "adminprefs_modified_source_code_url_label": "बदले गए स्रोत कोड के रिपॉज़िटरी का URL", + "none": "कुछ नहीं", + "videoinfo_started_streaming_x_ago": "`x` पहले स्ट्रीम करना शुरू किया", + "videoinfo_watch_on_youTube": "YouTube पर देखें", + "Video unavailable": "वीडियो उपलब्ध नहीं है", + "preferences_save_player_pos_label": "यहाँ से चलाना शुरू करें: ", + "crash_page_you_found_a_bug": "शायद आपको Invidious में कोई बग नज़र आ गया है!", + "videoinfo_youTube_embed_link": "एम्बेड करें", + "videoinfo_invidious_embed_link": "एम्बोड करने की कड़ी", + "download_subtitles": "उपशीर्षक - `x` (.vtt)", + "user_created_playlists": "बनाए गए `x` प्लेलिस्ट्स", + "user_saved_playlists": "सहेजे गए `x` प्लेलिस्ट्स", + "crash_page_before_reporting": "बग रिपोर्ट करने से पहले:", + "crash_page_switch_instance": "किसी दूसरे उदाहरण का इस्तेमाल करें", + "crash_page_read_the_faq": "अक्सर पूछे जाने वाले प्रश्न (FAQ) पढ़ें", + "crash_page_refresh": "पृष्ठ को एक बार साफ़ करें", + "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें" +} From fbc6b14424c449a122ef695189f6e23d5bd49a7f Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 2 May 2022 19:28:57 +0200 Subject: [PATCH 46/48] Update Russian translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Егор Ермаков --- locales/ru.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/ru.json b/locales/ru.json index a10bb0502..0199f61fb 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -5,8 +5,8 @@ "Subscribe": "Подписаться", "View channel on YouTube": "Смотреть канал на YouTube", "View playlist on YouTube": "Посмотреть плейлист на YouTube", - "newest": "самые свежие", - "oldest": "самые старые", + "newest": "сначала новые", + "oldest": "сначала старые", "popular": "популярные", "last": "недавние", "Next page": "Следующая страница", @@ -74,8 +74,8 @@ "dark": "темная", "light": "светлая", "preferences_thin_mode_label": "Облегчённое оформление: ", - "preferences_category_misc": "Прочие предпочтения", - "preferences_automatic_instance_redirect_label": "Автоматическое перенаправление на зеркало сайта (резервный вариант redirect.invidious.io): ", + "preferences_category_misc": "Прочие настройки", + "preferences_automatic_instance_redirect_label": "Автоматическое перенаправление на зеркало сайта (переход на redirect.invidious.io): ", "preferences_category_subscription": "Настройки подписок", "preferences_annotations_subscribed_label": "Всегда показывать аннотации в видео каналов, на которые вы подписаны? ", "Redirect homepage to feed: ": "Отображать видео с каналов, на которые вы подписаны, как главную страницу: ", From 44fe39821a97a9123ad832db693efad80ef6ae5a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 2 May 2022 19:28:57 +0200 Subject: [PATCH 47/48] Update Portuguese (Brazil) translation Co-authored-by: Vinicius --- locales/pt-BR.json | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index f3a05a1ae..2ee65272b 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -21,15 +21,15 @@ "No": "Não", "Import and Export Data": "Importar e Exportar Dados", "Import": "Importar", - "Import Invidious data": "Importar dados do Invidious", - "Import YouTube subscriptions": "Importar inscrições do YouTube", + "Import Invidious data": "Importar dados em JSON do Invidious", + "Import YouTube subscriptions": "Importar inscrições do YouTube/OPML", "Import FreeTube subscriptions (.db)": "Importar inscrições do FreeTube (.db)", "Import NewPipe subscriptions (.json)": "Importar inscrições do NewPipe (.json)", "Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)", "Export": "Exportar", "Export subscriptions as OPML": "Exportar inscrições como OPML", "Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportar inscrições como OPML (para NewPipe e FreeTube)", - "Export data as JSON": "Exportar dados como JSON", + "Export data as JSON": "Exportar dados Invidious como JSON", "Delete account?": "Excluir conta?", "History": "Histórico", "An alternative front-end to YouTube": "Uma interface alternativa para o YouTube", @@ -66,7 +66,7 @@ "preferences_related_videos_label": "Mostrar vídeos relacionados: ", "preferences_annotations_label": "Sempre mostrar anotações: ", "preferences_extend_desc_label": "Estenda automaticamente a descrição do vídeo: ", - "preferences_vr_mode_label": "Vídeos interativos de 360 graus: ", + "preferences_vr_mode_label": "Vídeos interativos de 360 graus (requer WebGL): ", "preferences_category_visual": "Preferências visuais", "preferences_player_style_label": "Estilo do tocador: ", "Dark mode: ": "Modo escuro: ", @@ -410,7 +410,7 @@ "crash_page_read_the_faq": "leu as Perguntas Frequentes (FAQ)", "generic_views_count": "{{count}} visualização", "generic_views_count_plural": "{{count}} visualizações", - "preferences_quality_option_dash": "DASH (qualidade adaptiva)", + "preferences_quality_option_dash": "DASH (qualidade adaptável)", "preferences_quality_option_hd720": "HD720", "preferences_quality_option_small": "Pequeno", "preferences_quality_dash_option_auto": "Auto", @@ -436,5 +436,10 @@ "user_saved_playlists": "`x` listas de reprodução salvas", "Video unavailable": "Vídeo indisponível", "videoinfo_started_streaming_x_ago": "Iniciou a transmissão a `x`", - "search_filters_title": "Filtro" + "search_filters_title": "Filtro", + "preferences_watch_history_label": "Ative o histórico de exibição: ", + "search_message_no_results": "Nenhum resultado encontrado.", + "search_message_change_filters_or_query": "Tente ampliar sua consulta de pesquisa e/ou alterar os filtros.", + "English (United Kingdom)": "Inglês (Reino Unido)", + "English (United States)": "Inglês (Estados Unidos)" } From a122286d48f96a929856a74bce4738bf0695dd66 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Mon, 2 May 2022 19:34:08 +0200 Subject: [PATCH 48/48] Add Hindi to i18n.cr --- src/invidious/helpers/i18n.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invidious/helpers/i18n.cr b/src/invidious/helpers/i18n.cr index 982b97d83..3f987b4d6 100644 --- a/src/invidious/helpers/i18n.cr +++ b/src/invidious/helpers/i18n.cr @@ -14,6 +14,7 @@ LOCALES_LIST = { "fi" => "Suomi", # Finnish "fr" => "Français", # French "he" => "עברית", # Hebrew + "hi" => "हिन्दी", # Hindi "hr" => "Hrvatski", # Croatian "hu-HU" => "Magyar Nyelv", # Hungarian "id" => "Bahasa Indonesia", # Indonesian