From 437f42250e381ab7652e07b4a413bb5d152356e1 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Mon, 7 Nov 2022 03:49:00 +0100 Subject: [PATCH 01/90] Watched marker --- src/invidious/views/components/item.ecr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 0e959ff2..e53fa075 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -99,7 +99,7 @@ <% else %> <% if !env.get("preferences").as(Preferences).thin_mode %> -
+
"> <% if env.get? "show_watched" %>
" method="post"> From 7b573817734dfd48fc6d1fbdc9a0a99f379f0ed1 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Mon, 7 Nov 2022 19:03:23 +0000 Subject: [PATCH 02/90] Added watch indicator --- assets/css/default.css | 13 ++++++++++ assets/js/watched_widget.js | 27 +++++++++++++++++++++ docker-compose.yml | 4 +-- src/invidious/views/components/item.ecr | 7 +++++- src/invidious/views/feeds/subscriptions.ecr | 3 ++- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index ab2b79e6..30a562e2 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -135,6 +135,9 @@ div.thumbnail { position: relative; box-sizing: border-box; } +div.thumbnail.thumbnail-watched { + background-color: rgba(255,255,255,.4); +} img.thumbnail { position: absolute; @@ -143,6 +146,16 @@ img.thumbnail { left: 0; top: 0; object-fit: cover; + z-index: -1; +} + +div.watched-indicator { + position: absolute; + left: 0; + bottom: 0; + height: 4px; + width: 100%; + background: red; } .length { diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index f1ac9cb4..10b33c1a 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -32,3 +32,30 @@ function mark_unwatched(target) { } }); } + + +var save_player_pos_key = 'save_player_pos'; + +function get_all_video_times() { + return helpers.storage.get(save_player_pos_key) || {}; +} + +var watchedIndicators = document.getElementsByClassName('watched-indicator'); +for (var i = 0; i < watchedIndicators.length; i++) { + var indicator = watchedIndicators[i]; + + var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; + var total = parseInt(indicator.getAttribute('data-length'), 10); + + var percentage = Math.round((watched_part / total) * 100); + + + if (percentage < 5) { + percentage = 5; + } + if (percentage > 90) { + percentage = 100; + } + + indicator.style.width = percentage + '%'; +} diff --git a/docker-compose.yml b/docker-compose.yml index eb83b020..48ee6a4b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: dockerfile: docker/Dockerfile restart: unless-stopped ports: - - "127.0.0.1:3000:3000" + - "3003:3000" environment: # Please read the following file for a comprehensive list of all available # configuration options and their associated syntax: @@ -23,7 +23,7 @@ services: dbname: invidious user: kemal password: kemal - host: invidious-db + host: invidious-invidious-db-1 port: 5432 check_tables: true # external_port: diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index e53fa075..d63dca14 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -99,7 +99,8 @@ <% else %> <% if !env.get("preferences").as(Preferences).thin_mode %> -
"> + <% item_watched = env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> +
"> <% if env.get? "show_watched" %> " method="post"> @@ -124,6 +125,10 @@ <% elsif item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> + + <% if item_watched %> +
+ <% end %>
<% end %>

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

diff --git a/src/invidious/views/feeds/subscriptions.ecr b/src/invidious/views/feeds/subscriptions.ecr index 8d56ad14..add1eefc 100644 --- a/src/invidious/views/feeds/subscriptions.ecr +++ b/src/invidious/views/feeds/subscriptions.ecr @@ -50,7 +50,6 @@ }.to_pretty_json %> -
<% videos.each do |item| %> @@ -58,6 +57,8 @@ <% end %>
+ +
<% if page > 1 %> From f604c1c68bbba81310ca2fd0a7283482840e0a26 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:15:42 +0100 Subject: [PATCH 03/90] Fixed thumbnails with darkreader, Added watched indicator in more locations --- assets/css/default.css | 16 +++++++++++----- assets/js/watched_widget.js | 4 +--- src/invidious/views/components/item.ecr | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index 30a562e2..890bd524 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -135,9 +135,7 @@ div.thumbnail { position: relative; box-sizing: border-box; } -div.thumbnail.thumbnail-watched { - background-color: rgba(255,255,255,.4); -} + img.thumbnail { position: absolute; @@ -146,7 +144,15 @@ img.thumbnail { left: 0; top: 0; object-fit: cover; - z-index: -1; +} + +div.watched-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255,255,255,.4); } div.watched-indicator { @@ -155,7 +161,7 @@ div.watched-indicator { bottom: 0; height: 4px; width: 100%; - background: red; + background-color: red; } .length { diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 10b33c1a..ffcdaad8 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -41,15 +41,13 @@ function get_all_video_times() { } var watchedIndicators = document.getElementsByClassName('watched-indicator'); +console.log('indicators', watchedIndicators.length); for (var i = 0; i < watchedIndicators.length; i++) { var indicator = watchedIndicators[i]; - var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; var total = parseInt(indicator.getAttribute('data-length'), 10); - var percentage = Math.round((watched_part / total) * 100); - if (percentage < 5) { percentage = 5; } diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index d63dca14..47d077cf 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -1,3 +1,5 @@ +<% item_watched = !item.is_a?(SearchChannel) && !item.is_a?(SearchPlaylist) && !item.is_a?(InvidiousPlaylist) && !item.is_a?(Category) && env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> +
<% case item when %> @@ -40,6 +42,11 @@ <% if item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> + + <% if item_watched %> +
+
+ <% end %>
<% end %>

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

@@ -67,6 +74,11 @@ <% elsif item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> + + <% if item_watched %> +
+
+ <% end %>
<% end %>

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

@@ -99,8 +111,7 @@ <% else %>
<% if !env.get("preferences").as(Preferences).thin_mode %> - <% item_watched = env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> -
"> +
<% if env.get? "show_watched" %> " method="post"> @@ -127,6 +138,7 @@ <% end %> <% if item_watched %> +
<% end %>
From c95ee10d6915bd1bb42e8e81f85848f1ad7b6240 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:18:24 +0100 Subject: [PATCH 04/90] Added parital watch indicator on more locations --- src/invidious/views/add_playlist_items.ecr | 2 ++ src/invidious/views/channel.ecr | 2 ++ src/invidious/views/edit_playlist.ecr | 2 ++ src/invidious/views/feeds/playlists.ecr | 2 ++ src/invidious/views/feeds/popular.ecr | 2 ++ src/invidious/views/feeds/trending.ecr | 2 ++ src/invidious/views/hashtag.ecr | 2 ++ src/invidious/views/playlist.ecr | 2 ++ src/invidious/views/playlists.ecr | 2 ++ src/invidious/views/search.ecr | 2 ++ 10 files changed, 20 insertions(+) diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr index 22870317..70575de3 100644 --- a/src/invidious/views/add_playlist_items.ecr +++ b/src/invidious/views/add_playlist_items.ecr @@ -39,6 +39,8 @@ <% end %>
+ + <% if query %> <%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%>
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index dea86abe..1295423e 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -110,6 +110,8 @@ <% end %>
+ +
<% if page > 1 %> diff --git a/src/invidious/views/edit_playlist.ecr b/src/invidious/views/edit_playlist.ecr index 89819ef0..100764c7 100644 --- a/src/invidious/views/edit_playlist.ecr +++ b/src/invidious/views/edit_playlist.ecr @@ -62,6 +62,8 @@ <% end %>
+ +
<% if page > 1 %> diff --git a/src/invidious/views/feeds/playlists.ecr b/src/invidious/views/feeds/playlists.ecr index a59344c4..f9064762 100644 --- a/src/invidious/views/feeds/playlists.ecr +++ b/src/invidious/views/feeds/playlists.ecr @@ -32,3 +32,5 @@ <%= rendered "components/item" %> <% end %>
+ + diff --git a/src/invidious/views/feeds/popular.ecr b/src/invidious/views/feeds/popular.ecr index e77f35b9..919002cd 100644 --- a/src/invidious/views/feeds/popular.ecr +++ b/src/invidious/views/feeds/popular.ecr @@ -16,3 +16,5 @@ <%= rendered "components/item" %> <% end %>
+ + diff --git a/src/invidious/views/feeds/trending.ecr b/src/invidious/views/feeds/trending.ecr index a35c4ee3..76218165 100644 --- a/src/invidious/views/feeds/trending.ecr +++ b/src/invidious/views/feeds/trending.ecr @@ -45,3 +45,5 @@ <%= rendered "components/item" %> <% end %>
+ + diff --git a/src/invidious/views/hashtag.ecr b/src/invidious/views/hashtag.ecr index 0ecfe832..6064af74 100644 --- a/src/invidious/views/hashtag.ecr +++ b/src/invidious/views/hashtag.ecr @@ -24,6 +24,8 @@ <%- end -%>
+ +
<%- if page > 1 -%> diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr index df3112db..1df047ba 100644 --- a/src/invidious/views/playlist.ecr +++ b/src/invidious/views/playlist.ecr @@ -106,6 +106,8 @@ <% end %>
+ +
<% if page > 1 %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index c8718e7b..6ce8b033 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -96,6 +96,8 @@ <% end %>
+ +
diff --git a/src/invidious/views/search.ecr b/src/invidious/views/search.ecr index 254449a1..c4960d08 100644 --- a/src/invidious/views/search.ecr +++ b/src/invidious/views/search.ecr @@ -37,6 +37,8 @@
<%- end -%> + +
<%- if query.page > 1 -%> From 5bcb5f3175247234c63e71ab3b35b7c3574a8fba Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:19:27 +0100 Subject: [PATCH 05/90] Removed console.log --- assets/js/watched_widget.js | 1 - 1 file changed, 1 deletion(-) diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index ffcdaad8..fb4275a3 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -41,7 +41,6 @@ function get_all_video_times() { } var watchedIndicators = document.getElementsByClassName('watched-indicator'); -console.log('indicators', watchedIndicators.length); for (var i = 0; i < watchedIndicators.length; i++) { var indicator = watchedIndicators[i]; var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; From c03f92baf7d2a46c3a9ec91c75da3f6d3d24ca57 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Tue, 8 Nov 2022 23:22:44 +0100 Subject: [PATCH 06/90] Fixed watch indicator when position is not saved --- assets/js/watched_widget.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index fb4275a3..3cf7c332 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -45,6 +45,9 @@ for (var i = 0; i < watchedIndicators.length; i++) { var indicator = watchedIndicators[i]; var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; var total = parseInt(indicator.getAttribute('data-length'), 10); + if (watched_part === undefined) { + watched_part = total; + } var percentage = Math.round((watched_part / total) * 100); if (percentage < 5) { From d3d9cfdd0d1d0739b88e34fbb39653131d475665 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Wed, 9 Nov 2022 00:32:38 +0100 Subject: [PATCH 07/90] Cleanup --- assets/css/default.css | 1 - assets/js/watched_widget.js | 1 - docker-compose.yml | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/assets/css/default.css b/assets/css/default.css index 890bd524..9edf3efa 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -136,7 +136,6 @@ div.thumbnail { box-sizing: border-box; } - img.thumbnail { position: absolute; width: 100%; diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 3cf7c332..d1b55d28 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -33,7 +33,6 @@ function mark_unwatched(target) { }); } - var save_player_pos_key = 'save_player_pos'; function get_all_video_times() { diff --git a/docker-compose.yml b/docker-compose.yml index 48ee6a4b..eb83b020 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,7 @@ services: dockerfile: docker/Dockerfile restart: unless-stopped ports: - - "3003:3000" + - "127.0.0.1:3000:3000" environment: # Please read the following file for a comprehensive list of all available # configuration options and their associated syntax: @@ -23,7 +23,7 @@ services: dbname: invidious user: kemal password: kemal - host: invidious-invidious-db-1 + host: invidious-db port: 5432 check_tables: true # external_port: From 4aa696fa6ea11959e72b7c084d0b55b2c5476a07 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Sat, 21 Jan 2023 23:08:24 +0100 Subject: [PATCH 08/90] Update assets/js/watched_widget.js with suggestion of AHOHNMYC Co-authored-by: AHOHNMYC <24810600+AHOHNMYC@users.noreply.github.com> --- assets/js/watched_widget.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index d1b55d28..02537111 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -39,11 +39,9 @@ function get_all_video_times() { return helpers.storage.get(save_player_pos_key) || {}; } -var watchedIndicators = document.getElementsByClassName('watched-indicator'); -for (var i = 0; i < watchedIndicators.length; i++) { - var indicator = watchedIndicators[i]; - var watched_part = get_all_video_times()[indicator.getAttribute('data-id')]; - var total = parseInt(indicator.getAttribute('data-length'), 10); +document.querySelectorAll('.watched-indicator').forEach(function (indicator) { + var watched_part = get_all_video_times()[indicator.dataset.id]; + var total = parseInt(indicator.dataset.length, 10); if (watched_part === undefined) { watched_part = total; } @@ -57,4 +55,4 @@ for (var i = 0; i < watchedIndicators.length; i++) { } indicator.style.width = percentage + '%'; -} +}); From 7fd205179b5707a2774d83866f5a35b2bd8cfe16 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Sat, 21 Jan 2023 23:24:22 +0100 Subject: [PATCH 09/90] Added suggestions --- src/invidious/views/components/item.ecr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 47d077cf..fa12374f 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -1,4 +1,4 @@ -<% item_watched = !item.is_a?(SearchChannel) && !item.is_a?(SearchPlaylist) && !item.is_a?(InvidiousPlaylist) && !item.is_a?(Category) && env.get("user") && env.get("user").as(User).watched && env.get("user").as(User).watched.index(item.id) != nil %> +<% item_watched = !item.is_a?(SearchChannel | SearchPlaylist | InvidiousPlaylist | Category) && env.get?("user").try &.as(User).watched.index(item.id) != nil %>
@@ -42,7 +42,7 @@ <% if item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> - + <% if item_watched %>
@@ -74,7 +74,7 @@ <% elsif item.length_seconds != 0 %>

<%= recode_length_seconds(item.length_seconds) %>

<% end %> - + <% if item_watched %>
From e7a9aeff9538903d22363d2abcee28c62dc10895 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Mon, 30 Jan 2023 10:49:23 -0500 Subject: [PATCH 10/90] Add username to auth token callback --- src/invidious/routes/account.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invidious/routes/account.cr b/src/invidious/routes/account.cr index 9bb73136..d01aee56 100644 --- a/src/invidious/routes/account.cr +++ b/src/invidious/routes/account.cr @@ -262,6 +262,7 @@ module Invidious::Routes::Account end query["token"] = access_token + query["username"] = user.email url.query = query.to_s env.redirect url.to_s From bf5175d1e979005f6d04c9d7639c9db4aa08fb7b Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 2 Feb 2023 11:52:31 -0500 Subject: [PATCH 11/90] Feat: Add api endpoint to resolve youtube urls --- src/invidious/routes/api/v1/misc.cr | 27 +++++++++++++++++++++++++++ src/invidious/routing.cr | 1 + 2 files changed, 28 insertions(+) diff --git a/src/invidious/routes/api/v1/misc.cr b/src/invidious/routes/api/v1/misc.cr index 43d360e6..9679b530 100644 --- a/src/invidious/routes/api/v1/misc.cr +++ b/src/invidious/routes/api/v1/misc.cr @@ -150,4 +150,31 @@ module Invidious::Routes::API::V1::Misc response end + + # resolve channel and clip urls, return the UCID + def self.resolve_url(env) + env.response.content_type = "application/json" + url = env.params.query["url"]? + + return error_json(400, "Missing URL to resolve") if !url + + begin + resolved_url = YoutubeAPI.resolve_url(url.as(String)) + endpoint = resolved_url["endpoint"] + if resolved_ucid = endpoint.dig?("watchEndpoint", "videoId") + elsif resolved_ucid = endpoint.dig?("browseEndpoint", "browseId") + elsif pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || "" + if pageType == "WEB_PAGE_TYPE_UNKNOWN" + return error_json(400, "Unknown url") + end + end + rescue ex + return error_json(500, ex) + end + JSON.build do |json| + json.object do + json.field "ucid", resolved_ucid.try &.as_s || "" + end + end + end end diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 157e6de7..fb9851a3 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -281,6 +281,7 @@ module Invidious::Routing get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist get "/api/v1/mixes/:rdid", {{namespace}}::Misc, :mixes + get "/api/v1/resolveurl", {{namespace}}::Misc, :resolve_url {% end %} end end From c162c7ff3f27498bd374b674bf7ca9b0c0790cc8 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 2 Feb 2023 18:20:14 -0500 Subject: [PATCH 12/90] add pageType --- src/invidious/routes/api/v1/misc.cr | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/invidious/routes/api/v1/misc.cr b/src/invidious/routes/api/v1/misc.cr index 9679b530..e499f4d6 100644 --- a/src/invidious/routes/api/v1/misc.cr +++ b/src/invidious/routes/api/v1/misc.cr @@ -161,12 +161,11 @@ module Invidious::Routes::API::V1::Misc begin resolved_url = YoutubeAPI.resolve_url(url.as(String)) endpoint = resolved_url["endpoint"] + pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || "" if resolved_ucid = endpoint.dig?("watchEndpoint", "videoId") elsif resolved_ucid = endpoint.dig?("browseEndpoint", "browseId") - elsif pageType = endpoint.dig?("commandMetadata", "webCommandMetadata", "webPageType").try &.as_s || "" - if pageType == "WEB_PAGE_TYPE_UNKNOWN" - return error_json(400, "Unknown url") - end + elsif pageType == "WEB_PAGE_TYPE_UNKNOWN" + return error_json(400, "Unknown url") end rescue ex return error_json(500, ex) @@ -174,6 +173,7 @@ module Invidious::Routes::API::V1::Misc JSON.build do |json| json.object do json.field "ucid", resolved_ucid.try &.as_s || "" + json.field "pageType", pageType end end end From b2589c74bedb73a1ab6e0afe1a921b97f80c4b8e Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Feb 2023 19:14:02 -0500 Subject: [PATCH 13/90] Add API for import/export --- src/invidious/routes/api/v1/authenticated.cr | 49 ++++++++++++++++++++ src/invidious/routing.cr | 3 ++ 2 files changed, 52 insertions(+) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index 421355bb..c6042e40 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -31,6 +31,55 @@ module Invidious::Routes::API::V1::Authenticated env.response.status_code = 204 end + def self.export_invidious(env) + env.response.content_type = "application/json" + user = env.get("user").as(User) + + playlists = Invidious::Database::Playlists.select_like_iv(user.email) + + return JSON.build do |json| + json.object do + json.field "subscriptions", user.subscriptions + json.field "watch_history", user.watched + json.field "preferences", user.preferences + json.field "playlists" do + json.array do + playlists.each do |playlist| + json.object do + json.field "title", playlist.title + json.field "description", html_to_content(playlist.description_html) + json.field "privacy", playlist.privacy.to_s + json.field "videos" do + json.array do + Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| + json.string video_id + end + end + end + end + end + end + end + end + end + end + + def self.import_invidious(env) + user = env.get("user").as(User) + + begin + if body = env.request.body + body = env.request.body.not_nil!.gets_to_end + else + body = "{}" + end + Invidious::User::Import.from_invidious(user, body) + rescue + end + + env.response.status_code = 204 + end + def self.feed(env) env.response.content_type = "application/json" diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index 157e6de7..d5766b90 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -254,6 +254,9 @@ module Invidious::Routing get "/api/v1/auth/preferences", {{namespace}}::Authenticated, :get_preferences post "/api/v1/auth/preferences", {{namespace}}::Authenticated, :set_preferences + get "/api/v1/auth/export/invidious", {{namespace}}::Authenticated, :export_invidious + post "/api/v1/auth/import/invidious", {{namespace}}::Authenticated, :import_invidious + get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions From 2606decd21a84ac3cba914f327f60a8403398ed9 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Sun, 5 Feb 2023 15:00:11 -0500 Subject: [PATCH 14/90] Refactor export function --- src/invidious/routes/api/v1/authenticated.cr | 28 +--------------- src/invidious/routes/subscriptions.cr | 26 +-------------- src/invidious/user/exports.cr | 35 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 52 deletions(-) create mode 100644 src/invidious/user/exports.cr diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index c6042e40..6b935312 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -35,33 +35,7 @@ module Invidious::Routes::API::V1::Authenticated env.response.content_type = "application/json" user = env.get("user").as(User) - playlists = Invidious::Database::Playlists.select_like_iv(user.email) - - return JSON.build do |json| - json.object do - json.field "subscriptions", user.subscriptions - json.field "watch_history", user.watched - json.field "preferences", user.preferences - json.field "playlists" do - json.array do - playlists.each do |playlist| - json.object do - json.field "title", playlist.title - json.field "description", html_to_content(playlist.description_html) - json.field "privacy", playlist.privacy.to_s - json.field "videos" do - json.array do - Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| - json.string video_id - end - end - end - end - end - end - end - end - end + return Invidious::User::Export.to_invidious(user) end def self.import_invidious(env) diff --git a/src/invidious/routes/subscriptions.cr b/src/invidious/routes/subscriptions.cr index 7b1fa876..3090e026 100644 --- a/src/invidious/routes/subscriptions.cr +++ b/src/invidious/routes/subscriptions.cr @@ -106,31 +106,7 @@ module Invidious::Routes::Subscriptions env.response.headers["content-disposition"] = "attachment" playlists = Invidious::Database::Playlists.select_like_iv(user.email) - return JSON.build do |json| - json.object do - json.field "subscriptions", user.subscriptions - json.field "watch_history", user.watched - json.field "preferences", user.preferences - json.field "playlists" do - json.array do - playlists.each do |playlist| - json.object do - json.field "title", playlist.title - json.field "description", html_to_content(playlist.description_html) - json.field "privacy", playlist.privacy.to_s - json.field "videos" do - json.array do - Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| - json.string video_id - end - end - end - end - end - end - end - end - end + return Invidious::User::Export.to_invidious(user) else env.response.content_type = "application/xml" env.response.headers["content-disposition"] = "attachment" diff --git a/src/invidious/user/exports.cr b/src/invidious/user/exports.cr new file mode 100644 index 00000000..32be0ca2 --- /dev/null +++ b/src/invidious/user/exports.cr @@ -0,0 +1,35 @@ +struct Invidious::User + module Export + extend self + + def to_invidious(user : User) + playlists = Invidious::Database::Playlists.select_like_iv(user.email) + + return JSON.build do |json| + json.object do + json.field "subscriptions", user.subscriptions + json.field "watch_history", user.watched + json.field "preferences", user.preferences + json.field "playlists" do + json.array do + playlists.each do |playlist| + json.object do + json.field "title", playlist.title + json.field "description", html_to_content(playlist.description_html) + json.field "privacy", playlist.privacy.to_s + json.field "videos" do + json.array do + Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| + json.string video_id + end + end + end + end + end + end + end + end + end + end + end # module +end From 47a5b98e2554b32946864bc3320478d0dcc1daf8 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Sun, 5 Feb 2023 15:43:58 -0500 Subject: [PATCH 15/90] Remove unused db call --- src/invidious/routes/subscriptions.cr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/invidious/routes/subscriptions.cr b/src/invidious/routes/subscriptions.cr index 3090e026..0704c05e 100644 --- a/src/invidious/routes/subscriptions.cr +++ b/src/invidious/routes/subscriptions.cr @@ -104,7 +104,6 @@ module Invidious::Routes::Subscriptions if format == "json" env.response.content_type = "application/json" env.response.headers["content-disposition"] = "attachment" - playlists = Invidious::Database::Playlists.select_like_iv(user.email) return Invidious::User::Export.to_invidious(user) else From c37d8e36645d23afedff2729b8ad504cc5ba0655 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Sun, 5 Feb 2023 15:49:56 -0500 Subject: [PATCH 16/90] Use CONFIG.playlist_length_limit when exporting playlists --- src/invidious/user/exports.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/user/exports.cr b/src/invidious/user/exports.cr index 32be0ca2..b52503c9 100644 --- a/src/invidious/user/exports.cr +++ b/src/invidious/user/exports.cr @@ -19,7 +19,7 @@ struct Invidious::User json.field "privacy", playlist.privacy.to_s json.field "videos" do json.array do - Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id| + Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: CONFIG.playlist_length_limit).each do |video_id| json.string video_id end end From 28424d0e881c8595bbc5797b9ef46e98103fe6d6 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Feb 2023 09:23:26 -0500 Subject: [PATCH 17/90] Ignore casing for trending type in api --- src/invidious/trending.cr | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr index 1f957081..d164c37f 100644 --- a/src/invidious/trending.cr +++ b/src/invidious/trending.cr @@ -4,11 +4,14 @@ def fetch_trending(trending_type, region, locale) plid = nil - if trending_type == "Music" + trending_type ||= "default" + trending_type = trending_type.downcase + + if trending_type == "music" params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D" - elsif trending_type == "Gaming" + elsif trending_type == "gaming" params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D" - elsif trending_type == "Movies" + elsif trending_type == "movies" params = "4gIKGgh0cmFpbGVycw%3D%3D" else # Default params = "" From 97825be10c4acf98962c9e65d63305cc77c21021 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:52:53 -0500 Subject: [PATCH 18/90] add missing authorVerified to api --- src/invidious/helpers/serialized_yt_data.cr | 1 + src/invidious/routes/api/v1/channels.cr | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr index 635f0984..c1874780 100644 --- a/src/invidious/helpers/serialized_yt_data.cr +++ b/src/invidious/helpers/serialized_yt_data.cr @@ -74,6 +74,7 @@ struct SearchVideo json.field "author", self.author json.field "authorId", self.ucid json.field "authorUrl", "/channel/#{self.ucid}" + json.field "authorVerified", self.author_verified json.field "videoThumbnails" do Invidious::JSONify::APIv1.thumbnails(json, self.id) diff --git a/src/invidious/routes/api/v1/channels.cr b/src/invidious/routes/api/v1/channels.cr index ca2b2734..bcb4db2c 100644 --- a/src/invidious/routes/api/v1/channels.cr +++ b/src/invidious/routes/api/v1/channels.cr @@ -89,6 +89,8 @@ module Invidious::Routes::API::V1::Channels json.field "descriptionHtml", channel.description_html json.field "allowedRegions", channel.allowed_regions + json.field "tabs", channel.tabs + json.field "authorVerified", channel.verified json.field "latestVideos" do json.array do From b893bdac0d6b76a61e2cd972b29e44cf5b9c88f0 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Feb 2023 22:02:35 -0500 Subject: [PATCH 19/90] parse isPinned, add support for strikethrough --- src/invidious/comments.cr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index d691ca36..357a461c 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -181,6 +181,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "content", html_to_content(content_html) json.field "contentHtml", content_html + json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) + json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) @@ -670,6 +672,7 @@ def content_to_comment_html(content, video_id : String? = "") end text = "#{text}" if run["bold"]? + text = "#{text}" if run["strikethrough"]? text = "#{text}" if run["italics"]? text From e0c70d34cc3f937149d5c36c76aed8d8b57b4de5 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 9 Feb 2023 17:13:21 -0500 Subject: [PATCH 20/90] Make sure pinnedCommentBadge isn't equal to false Co-authored-by: Samantaz Fox --- src/invidious/comments.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 357a461c..41b0efa8 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -181,7 +181,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "content", html_to_content(content_html) json.field "contentHtml", content_html - json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) + json.field "isPinned", (node_comment["pinnedCommentBadge"]?.try(&.as_bool) == true) json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) From 838cbeffcc7c8f85c83f6ab3e97362f803bd766c Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Sat, 11 Feb 2023 08:41:26 -0500 Subject: [PATCH 21/90] Use case statement for trending_type Co-Authored-By: Samantaz Fox --- src/invidious/trending.cr | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr index d164c37f..134eb437 100644 --- a/src/invidious/trending.cr +++ b/src/invidious/trending.cr @@ -4,14 +4,12 @@ def fetch_trending(trending_type, region, locale) plid = nil - trending_type ||= "default" - trending_type = trending_type.downcase - - if trending_type == "music" + case trending_type.try &.downcase + when "music" params = "4gINGgt5dG1hX2NoYXJ0cw%3D%3D" - elsif trending_type == "gaming" + when "gaming" params = "4gIcGhpnYW1pbmdfY29ycHVzX21vc3RfcG9wdWxhcg%3D%3D" - elsif trending_type == "movies" + when "movies" params = "4gIKGgh0cmFpbGVycw%3D%3D" else # Default params = "" From 87342e4efd4258f52d2b34f0e5af0fcf7ca09f90 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 12 Feb 2023 17:57:07 +0100 Subject: [PATCH 22/90] Comments: Revert "isPinned" to a nil check "pinnedCommentBadge" is not a boolean, but a complex structure. This commit fixes a wrong assumption I had during the rewiew of https://github.com/iv-org/invidious/pull/3626 --- src/invidious/comments.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 41b0efa8..357a461c 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -181,7 +181,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "content", html_to_content(content_html) json.field "contentHtml", content_html - json.field "isPinned", (node_comment["pinnedCommentBadge"]?.try(&.as_bool) == true) + json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) From 48306564843569713cf7ccda63451946419fa376 Mon Sep 17 00:00:00 2001 From: AHOHNMYC Date: Thu, 26 Jan 2023 07:58:32 +0000 Subject: [PATCH 23/90] Update Russian translation --- locales/ru.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index e54937a6..77057f53 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -488,5 +488,9 @@ "search_filters_duration_option_medium": "Средние (4 - 20 минут)", "search_filters_apply_button": "Применить фильтры", "Popular enabled: ": "Популярное включено: ", - "error_video_not_in_playlist": "Запрошенного видео нет в этом плейлисте.
Нажмите тут, чтобы вернуться к странице плейлиста." + "error_video_not_in_playlist": "Запрошенного видео нет в этом плейлисте. Нажмите тут, чтобы вернуться к странице плейлиста.", + "channel_tab_playlists_label": "Плейлисты", + "channel_tab_channels_label": "Каналы", + "channel_tab_streams_label": "Живое вещание", + "channel_tab_shorts_label": "Shorts" } From bd00b4c730c1fd416751f74c10fe492a02f6acd2 Mon Sep 17 00:00:00 2001 From: SC Date: Thu, 26 Jan 2023 19:26:36 +0000 Subject: [PATCH 24/90] Update Portuguese translation --- locales/pt.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/pt.json b/locales/pt.json index 2facba94..79a39ab6 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -472,5 +472,9 @@ "search_filters_type_option_all": "Qualquer tipo", "search_filters_duration_option_none": "Qualquer duração", "Popular enabled: ": "Página \"popular\" ativada: ", - "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução." + "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução.", + "channel_tab_playlists_label": "Listas de reprodução", + "channel_tab_channels_label": "Canais", + "channel_tab_shorts_label": "Curtos", + "channel_tab_streams_label": "Diretos" } From b2f93dc89c4c2271bdb3e7e52510813ee7296d88 Mon Sep 17 00:00:00 2001 From: eightyy8 Date: Tue, 31 Jan 2023 17:22:42 +0000 Subject: [PATCH 25/90] Update Russian translation --- locales/ru.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index 77057f53..85628d0f 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -379,7 +379,7 @@ "Turkish (auto-generated)": "Турецкий (созданы автоматически)", "Vietnamese (auto-generated)": "Вьетнамский (созданы автоматически)", "footer_documentation": "Документация", - "adminprefs_modified_source_code_url_label": "Ссылка на нашу ветку репозитория", + "adminprefs_modified_source_code_url_label": "URL-адрес репозитория измененного исходного кода", "none": "ничего", "videoinfo_watch_on_youTube": "Смотреть на YouTube", "videoinfo_youTube_embed_link": "Версия для встраивания", From f4de962dc270a399d49eb659b9fc2e30e991a6b9 Mon Sep 17 00:00:00 2001 From: maboroshin Date: Tue, 31 Jan 2023 01:16:27 +0000 Subject: [PATCH 26/90] Update Japanese translation --- locales/ja.json | 107 ++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/locales/ja.json b/locales/ja.json index a392abfe..9df1477b 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -53,12 +53,12 @@ "E-mail": "メールアドレス", "Google verification code": "Google 認証コード", "Preferences": "設定", - "preferences_category_player": "プレイヤー設定", + "preferences_category_player": "プレイヤーの設定", "preferences_video_loop_label": "常にループ: ", "preferences_autoplay_label": "自動再生: ", "preferences_continue_label": "デフォルトで次を再生: ", "preferences_continue_autoplay_label": "次の動画を自動再生: ", - "preferences_listen_label": "デフォルトでオーディオモードを使用: ", + "preferences_listen_label": "デフォルトで音声モードを使用: ", "preferences_local_label": "動画をプロキシーに通す: ", "preferences_speed_label": "デフォルトの再生速度: ", "preferences_quality_label": "優先する画質: ", @@ -73,14 +73,14 @@ "preferences_extend_desc_label": "動画の説明文を自動的に拡張: ", "preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ", "preferences_category_visual": "外観設定", - "preferences_player_style_label": "プレイヤースタイル: ", + "preferences_player_style_label": "プレイヤーのスタイル: ", "Dark mode: ": "ダークモード: ", "preferences_dark_mode_label": "テーマ: ", "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: ": "ホームからフィードにリダイレクト: ", @@ -117,8 +117,8 @@ "Registration enabled: ": "登録を有効化: ", "Report statistics: ": "統計を報告: ", "Save preferences": "設定を保存", - "Subscription manager": "登録チャンネルマネージャー", - "Token manager": "トークンマネージャー", + "Subscription manager": "登録チャンネルの管理", + "Token manager": "トークンの管理", "Token": "トークン", "tokens_count_0": "{{count}} 個のトークン", "Import/export": "インポート/エクスポート", @@ -128,7 +128,7 @@ "subscriptions_unseen_notifs_count_0": "{{count}} 個の未読通知", "search": "検索", "Log out": "ログアウト", - "Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開されています。", + "Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開", "Source available here.": "ソースはここで閲覧可能です。", "View JavaScript license information.": "JavaScript ライセンス情報", "View privacy policy.": "プライバシーポリシー", @@ -136,24 +136,24 @@ "Public": "公開", "Unlisted": "限定公開", "Private": "非公開", - "View all playlists": "再生リストをすべて見る", + "View all playlists": "すべての再生リストを表示", "Updated `x` ago": "`x`前に更新", "Delete playlist `x`?": "再生リスト `x` を削除しますか?", "Delete playlist": "再生リストを削除", "Create playlist": "再生リストを作成", "Title": "タイトル", - "Playlist privacy": "再生リストのプライバシー", + "Playlist privacy": "再生リストの公開設定", "Editing playlist `x`": "再生リスト `x` を編集中", - "Show more": "表示を増やす", - "Show less": "表示を減らす", + "Show more": "もっと見る", + "Show less": "表示を少なく", "Watch on YouTube": "YouTube で視聴", - "Switch Invidious Instance": "Invidiousインスタンスの変更", + "Switch Invidious Instance": "Invidious インスタンスの変更", "Hide annotations": "アノテーションを隠す", "Show annotations": "アノテーションを表示", "Genre: ": "ジャンル: ", "License: ": "ライセンス: ", "Family friendly? ": "家族向け: ", - "Wilson score: ": "ウィルソンスコア: ", + "Wilson score: ": "ウィルソン得点区間: ", "Engagement: ": "エンゲージメント: ", "Whitelisted regions: ": "ホワイトリストの地域: ", "Blacklisted regions: ": "ブラックリストの地域: ", @@ -181,11 +181,11 @@ "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": "パスワードを空にすることはできません", + "Please sign in using 'Log in with Google'": "「Google でログイン」を使用してログインしてください", + "Password cannot be empty": "パスワードは空にできません", "Password cannot be longer than 55 characters": "パスワードは55文字より長くできません", - "Please log in": "ログインをしてください", - "Invidious Private Feed for `x`": "`x` の Invidious プライベートフィード", + "Please log in": "ログインしてください", + "Invidious Private Feed for `x`": "`x` 個人の Invidious によるフィード", "channel:`x`": "チャンネル:`x`", "Deleted or invalid channel": "削除済みまたは無効なチャンネルです", "This channel does not exist.": "このチャンネルは存在しません。", @@ -194,18 +194,18 @@ "comments_view_x_replies_0": "{{count}} 件の返信を見る", "`x` ago": "`x`前", "Load more": "もっと読み込む", - "comments_points_count_0": "{{count}} ポイント", + "comments_points_count_0": "{{count}}点", "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": "非表示項目 \"challenge\" は必須項目です", - "Hidden field \"token\" is a required field": "非表示項目 \"token\" は必須項目です", + "Hidden field \"challenge\" is a required field": "非表示項目 challenge は必須項目です", + "Hidden field \"token\" is a required field": "非表示項目 token は必須項目です", "Erroneous challenge": "チャレンジが間違っています", "Erroneous token": "トークンが間違っています", "No such user": "ユーザーが存在しません", - "Token is expired, please try again": "トークンが期限切れです。再度試してください", + "Token is expired, please try again": "トークンが期限切れです。再度お試しください", "English": "英語", "English (auto-generated)": "英語 (自動生成)", "Afrikaans": "アフリカーンス語", @@ -313,7 +313,7 @@ "Yoruba": "ヨルバ語", "Zulu": "ズール語", "generic_count_years_0": "{{count}}年", - "generic_count_months_0": "{{count}}ヶ月", + "generic_count_months_0": "{{count}}か月", "generic_count_weeks_0": "{{count}}週", "generic_count_days_0": "{{count}}日", "generic_count_hours_0": "{{count}}時間", @@ -338,21 +338,21 @@ "(edited)": "(編集済み)", "YouTube comment permalink": "YouTube コメントのパーマリンク", "permalink": "パーマリンク", - "`x` marked it with a ❤": "`x` が❤を込めてマークしました", - "Audio mode": "オーディオモード", - "Video mode": "ビデオモード", + "`x` marked it with a ❤": "`x` が❤を送りました", + "Audio mode": "音声モード", + "Video mode": "動画モード", "channel_tab_videos_label": "動画", - "Playlists": "プレイリスト", + "Playlists": "再生リスト", "channel_tab_community_label": "コミュニティ", - "search_filters_sort_option_relevance": "関連", + "search_filters_sort_option_relevance": "関連度", "search_filters_sort_option_rating": "評価", - "search_filters_sort_option_date": "時刻", + "search_filters_sort_option_date": "アップロード日", "search_filters_sort_option_views": "再生回数", - "search_filters_type_label": "コンテンツの種類", + "search_filters_type_label": "種類", "search_filters_duration_label": "再生時間", - "search_filters_features_label": "機能", + "search_filters_features_label": "特徴", "search_filters_sort_label": "順番", - "search_filters_date_option_hour": "1時間前", + "search_filters_date_option_hour": "1時間以内", "search_filters_date_option_today": "今日", "search_filters_date_option_week": "今週", "search_filters_date_option_month": "今月", @@ -377,9 +377,9 @@ "search_filters_duration_option_short": "4 分未満", "footer_documentation": "文書", "footer_source_code": "ソースコード", - "footer_original_source_code": "ソースコード(元)", - "footer_modfied_source_code": "ソースコード(編集)", - "adminprefs_modified_source_code_url_label": "編集したソースコードのレポジトリーURL", + "footer_original_source_code": "ソースコード (元)", + "footer_modfied_source_code": "ソースコード (改変)", + "adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL", "search_filters_duration_option_long": "20 分以上", "preferences_region_label": "地域: ", "footer_donate_page": "寄付する", @@ -406,10 +406,10 @@ "preferences_quality_option_dash": "DASH (適応品質)", "preferences_quality_dash_option_worst": "最悪", "preferences_quality_dash_option_best": "最高", - "videoinfo_started_streaming_x_ago": "`x`分前に配信を開始", + "videoinfo_started_streaming_x_ago": "`x`前に配信を開始", "videoinfo_watch_on_youTube": "YouTube上で見る", - "user_created_playlists": "`x`が作成したプレイリスト", - "Video unavailable": "ビデオは利用できません", + "user_created_playlists": "`x`個の作成した再生リスト", + "Video unavailable": "動画は利用できません", "Chinese": "中国語", "Chinese (Taiwan)": "中国語 (台湾)", "Korean (auto-generated)": "韓国語 (自動生成)", @@ -434,24 +434,31 @@ "Vietnamese (auto-generated)": "ベトナム語 (自動生成)", "search_filters_title": "フィルタ", "search_filters_features_option_three_sixty": "360°", - "search_message_change_filters_or_query": "別のキーワードを試してみるか、検索フィルタを削除してください", - "search_message_no_results": "一致する検索結果はありませんでした", + "search_message_change_filters_or_query": "別の検索語句を試したり、検索フィルタを変更してください。", + "search_message_no_results": "一致する検索結果はありません。", "English (United States)": "英語 (アメリカ)", "search_filters_date_label": "アップロード日", "search_filters_features_option_vr180": "VR180", - "crash_page_switch_instance": "別のインスタンスを使用しようとしました", + "crash_page_switch_instance": "別のインスタンスを使用を試す", "crash_page_read_the_faq": "よくある質問 (FAQ) を読む", "Popular enabled: ": "人気動画を有効化 ", - "search_message_use_another_instance": " 別のインスタンスで検索することもできます。", + "search_message_use_another_instance": " 別のインスタンス上でも検索できます。", "search_filters_apply_button": "選択したフィルターを適用", - "user_saved_playlists": "`x` 個の保存済みプレイリスト", + "user_saved_playlists": "`x` 個の保存した再生リスト", "crash_page_you_found_a_bug": "Invidious でバグを見つけたようです。", - "crash_page_refresh": "ページを更新しようとしました", - "preferences_watch_history_label": "視聴履歴を有効化 ", - "search_filters_date_option_none": "任意の日付", - "search_filters_type_option_all": "いかなるタイプ", - "search_filters_duration_option_none": "任意の期間", - "search_filters_duration_option_medium": "ミディアム (4 ~ 20 分)", + "crash_page_refresh": "ページを更新を試す", + "preferences_watch_history_label": "再生履歴を有効化 ", + "search_filters_date_option_none": "すべて", + "search_filters_type_option_all": "すべての種類", + "search_filters_duration_option_none": "すべての長さ", + "search_filters_duration_option_medium": "4 ~ 20 分", "preferences_save_player_pos_label": "再生位置を保存: ", - "crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。" + "crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。", + "crash_page_report_issue": "上記が助けにならないなら、GitHub に新しい issue を作成し(英語が好ましい)、メッセージに次のテキストを含めてください(テキストは翻訳しない)。", + "crash_page_search_issue": "GitHub の既存の問題 (issue) を検索", + "channel_tab_streams_label": "ライブ", + "channel_tab_playlists_label": "再生リスト", + "error_video_not_in_playlist": "要求された動画はこの再生リスト内に存在しません。再生リストのホームへ。", + "channel_tab_shorts_label": "ショート", + "channel_tab_channels_label": "チャンネル" } From 20dc0a9e262bb3dd7d2a18314938ea497fd6e776 Mon Sep 17 00:00:00 2001 From: Mateus Date: Wed, 1 Feb 2023 03:37:53 +0000 Subject: [PATCH 27/90] Update Portuguese (Brazil) translation --- locales/pt-BR.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 112ed4b7..afd31ede 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -472,5 +472,9 @@ "search_filters_duration_option_medium": "Médio (4 - 20 minutos)", "search_filters_features_option_vr180": "VR180", "Popular enabled: ": "Popular habilitado: ", - "error_video_not_in_playlist": "O vídeo solicitado não existe nesta playlist. Clique aqui para acessar a página inicial da playlist." + "error_video_not_in_playlist": "O vídeo solicitado não existe nesta playlist. Clique aqui para acessar a página inicial da playlist.", + "channel_tab_channels_label": "Canais", + "channel_tab_playlists_label": "Listas de reprodução", + "channel_tab_shorts_label": "Curtos", + "channel_tab_streams_label": "Ao Vivo" } From eb7588f1a0989efd95da28a3598ee956c2a989e3 Mon Sep 17 00:00:00 2001 From: Goudarz Jafari Date: Mon, 30 Jan 2023 10:22:38 +0000 Subject: [PATCH 28/90] Update Persian translation --- locales/fa.json | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/locales/fa.json b/locales/fa.json index f2ca2745..fe72a1e8 100644 --- a/locales/fa.json +++ b/locales/fa.json @@ -408,9 +408,9 @@ "preferences_region_label": "کشور محتوا: ", "footer_documentation": "مستندات", "footer_original_source_code": "کد منبع اصلی", - "search_filters_duration_option_long": "بلند (> 20 دقیقه)", + "search_filters_duration_option_long": "بلند (> ۲۰ دقیقه)", "adminprefs_modified_source_code_url_label": "URL مخزن کد منبع ویریش شده", - "search_filters_duration_option_short": "کوتاه (< 4 دقیقه)", + "search_filters_duration_option_short": "کوتاه (< ۴ دقیقه)", "search_filters_title": "پالایه", "Chinese (Hong Kong)": "چینی (هنگ‌کنگ)", "Dutch (auto-generated)": "هلندی (تولید خودکار)", @@ -424,5 +424,26 @@ "search_message_no_results": "نتیجه‌ای یافت نشد.", "search_message_change_filters_or_query": "سعی کنید جست‌و‌جوی خود را وسیع‌تر کنید و/یا فیلترها را تغییر دهید.", "Chinese (China)": "چینی (چین)", - "German (auto-generated)": "آلمانی (تولید خودکار)" + "German (auto-generated)": "آلمانی (تولید خودکار)", + "Japanese (auto-generated)": "ژاپنی (تولید خودکار)", + "Korean (auto-generated)": "کره‌ای (تولید خودکار)", + "Portuguese (Brazil)": "پرتغالی (برزیل)", + "search_filters_apply_button": "اعمال فیلترهای انتخاب شده", + "Italian (auto-generated)": "ایتالیایی (تولید خودکار)", + "Vietnamese (auto-generated)": "ویتنامی (تولید خودکار)", + "search_filters_type_option_all": "هر نوعی", + "search_filters_duration_option_none": "هر مدت زمانی", + "search_filters_date_label": "تاریخ بارگذاری", + "search_filters_date_option_none": "هر تاریخی", + "user_created_playlists": "`x` فهرست پخش ایجاد شد", + "Interlingue": "سرخپوستی", + "Russian (auto-generated)": "روسی (تولید خودکار)", + "Spanish (auto-generated)": "اسپانیایی (تولید خودکار)", + "search_filters_duration_option_medium": "متوسط (۴ تا ۲۰ دقیقه)", + "Portuguese (auto-generated)": "پرتغالی (تولید خودکار)", + "Cantonese (Hong Kong)": "کانتونی (هنگ کنگ)", + "Spanish (Spain)": "اسپانیایی (اسپانیا)", + "Turkish (auto-generated)": "ترکی (تولید خودکار)", + "search_filters_features_option_vr180": "VR180", + "Spanish (Mexico)": "اسپانیایی (مکزیک)" } From 5534cd87f84f685b4ecb40e9102f6f6f9186a0bf Mon Sep 17 00:00:00 2001 From: Damjan Gerl Date: Sun, 29 Jan 2023 16:38:35 +0000 Subject: [PATCH 29/90] Update Slovenian translation --- locales/sl.json | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/locales/sl.json b/locales/sl.json index f27bb20d..9a4a1bde 100644 --- a/locales/sl.json +++ b/locales/sl.json @@ -206,7 +206,7 @@ "generic_count_years_2": "{{count}} leti", "generic_count_years_3": "{{count}} leti", "generic_count_days_0": "{{count}} dnevom", - "generic_count_days_1": "{{count}} dnevi", + "generic_count_days_1": "{{count}} dnevoma", "generic_count_days_2": "{{count}} dnevi", "generic_count_days_3": "{{count}} dnevi", "generic_count_hours_0": "{{count}} uro", @@ -246,10 +246,10 @@ "generic_videos_count_1": "{{count}} videa", "generic_videos_count_2": "{{count}} videi", "generic_videos_count_3": "{{count}} videov", - "generic_views_count_0": "{{count}} ogled", - "generic_views_count_1": "{{count}} ogleda", - "generic_views_count_2": "{{count}} ogledi", - "generic_views_count_3": "{{count}} ogledov", + "generic_views_count_0": "Ogledov: {{count}}", + "generic_views_count_1": "Ogledov: {{count}}", + "generic_views_count_2": "Ogledov: {{count}}", + "generic_views_count_3": "Ogledov: {{count}}", "generic_playlists_count_0": "{{count}} seznam predvajanja", "generic_playlists_count_1": "{{count}} seznama predvajanja", "generic_playlists_count_2": "{{count}} seznami predvajanja", @@ -495,7 +495,7 @@ "footer_modfied_source_code": "Spremenjena izvorna koda", "user_created_playlists": "`x` ustvarjenih seznamov predvajanja", "adminprefs_modified_source_code_url_label": "URL do shrambe spremenjene izvorne kode", - "videoinfo_youTube_embed_link": "Vdelati", + "videoinfo_youTube_embed_link": "Vdelaj", "videoinfo_invidious_embed_link": "Povezava za vdelavo", "crash_page_switch_instance": "poskušal/a uporabiti drugo instanco", "download_subtitles": "Podnapisi - `x` (.vtt)", @@ -504,5 +504,9 @@ "crash_page_search_issue": "preiskal/a obstoječe težave na GitHubu", "crash_page_report_issue": "Če nič od navedenega ni pomagalo, prosim odpri novo težavo v GitHubu (po možnosti v angleščini) in v svoje sporočilo vključi naslednje besedilo (tega besedila NE prevajaj):", "Popular enabled: ": "Priljubljeni omogočeni: ", - "error_video_not_in_playlist": "Zahtevani videoposnetek ne obstaja na tem seznamu predvajanja. Klikni tukaj za domačo stran seznama predvajanja." + "error_video_not_in_playlist": "Zahtevani videoposnetek ne obstaja na tem seznamu predvajanja. Klikni tukaj za domačo stran seznama predvajanja.", + "channel_tab_playlists_label": "Seznami predvajanja", + "channel_tab_shorts_label": "Kratki videoposnetki", + "channel_tab_channels_label": "Kanali", + "channel_tab_streams_label": "Prenosi v živo" } From 7ae9dabe3c5491f476bdbb1f9dadc7294fe1927a Mon Sep 17 00:00:00 2001 From: Matthaiks Date: Thu, 2 Feb 2023 22:31:10 +0000 Subject: [PATCH 30/90] Update Polish translation --- locales/pl.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/locales/pl.json b/locales/pl.json index b9c2a638..2dd3ed87 100644 --- a/locales/pl.json +++ b/locales/pl.json @@ -67,7 +67,7 @@ "preferences_annotations_label": "Domyślnie pokazuj adnotacje: ", "preferences_extend_desc_label": "Automatycznie rozwijaj opisy filmów: ", "preferences_vr_mode_label": "Interaktywne filmy 360 stopni (wymaga WebGL): ", - "preferences_category_visual": "Preferencje Wizualne", + "preferences_category_visual": "Preferencje wizualne", "preferences_player_style_label": "Styl odtwarzacza: ", "Dark mode: ": "Ciemny motyw: ", "preferences_dark_mode_label": "Motyw: ", @@ -443,7 +443,7 @@ "user_saved_playlists": "`x` zapisanych playlist", "Video unavailable": "Film niedostępny", "preferences_save_player_pos_label": "Zapisz pozycję odtwarzania: ", - "preferences_region_label": "Region zawartości: ", + "preferences_region_label": "Kraj treści: ", "Released under the AGPLv3 on Github.": "Wydany na licencji AGPLv3 na GitHub.", "search_filters_duration_option_short": "Krótka (< 4 minut)", "search_filters_duration_option_long": "Długa (> 20 minut)", @@ -481,7 +481,7 @@ "search_message_no_results": "Nie znaleziono wyników.", "preferences_watch_history_label": "Włącz historię oglądania: ", "search_filters_apply_button": "Zastosuj wybrane filtry", - "search_message_change_filters_or_query": "Spróbuj poszerzyć zapytanie i/lub zmienić filtry.", + "search_message_change_filters_or_query": "Spróbuj poszerzyć zapytanie wyszukiwania i/lub zmienić filtry.", "search_filters_date_label": "Data przesłania", "search_filters_features_option_vr180": "VR180", "search_filters_date_option_none": "Dowolna data", @@ -492,5 +492,8 @@ "channel_tab_streams_label": "Na żywo", "channel_tab_channels_label": "Kanały", "channel_tab_playlists_label": "Playlisty", - "channel_tab_shorts_label": "Shorts" + "channel_tab_shorts_label": "Shorts", + "Music in this video": "Muzyka w tym filmie", + "Artist: ": "Wykonawca: ", + "Album: ": "Album: " } From 45c99190b2c1ebf7ea47667bd2404eb5031724ab Mon Sep 17 00:00:00 2001 From: Rex_sa Date: Fri, 3 Feb 2023 06:20:45 +0000 Subject: [PATCH 31/90] Update Arabic translation --- locales/ar.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ar.json b/locales/ar.json index 55dea5f3..181ff933 100644 --- a/locales/ar.json +++ b/locales/ar.json @@ -540,5 +540,8 @@ "channel_tab_shorts_label": "الفيديوهات القصيرة", "channel_tab_streams_label": "البث المباشر", "channel_tab_playlists_label": "قوائم التشغيل", - "channel_tab_channels_label": "القنوات" + "channel_tab_channels_label": "القنوات", + "Music in this video": "الموسيقى في هذا الفيديو", + "Album: ": "الألبوم: ", + "Artist: ": "الفنان: " } From 4ca23f2d51ea29c267cfdaaafc8cc5999aa825d4 Mon Sep 17 00:00:00 2001 From: atilluF Date: Sun, 5 Feb 2023 13:45:52 +0000 Subject: [PATCH 32/90] Update Italian translation --- locales/it.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/it.json b/locales/it.json index f47b032e..c60f760b 100644 --- a/locales/it.json +++ b/locales/it.json @@ -476,5 +476,8 @@ "channel_tab_playlists_label": "Playlist", "channel_tab_channels_label": "Canali", "channel_tab_streams_label": "Livestream", - "channel_tab_community_label": "Comunità" + "channel_tab_community_label": "Comunità", + "Music in this video": "Musica in questo video", + "Artist: ": "Artista: ", + "Album: ": "Album: " } From c82272155ed0e6bca6d3372303a771c5c9f317ad Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Thu, 2 Feb 2023 21:42:40 +0000 Subject: [PATCH 33/90] Update Spanish translation --- locales/es.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index 59d6b145..6cf721f3 100644 --- a/locales/es.json +++ b/locales/es.json @@ -476,5 +476,8 @@ "channel_tab_streams_label": "Directos", "channel_tab_channels_label": "Canales", "channel_tab_shorts_label": "Cortos", - "channel_tab_playlists_label": "Listas de reproducción" + "channel_tab_playlists_label": "Listas de reproducción", + "Music in this video": "Música en este vídeo", + "Artist: ": "Artista: ", + "Album: ": "Álbum: " } From c1c6f67ad30b5d34bc714a5b4b28934b3bd8cd1f Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Thu, 2 Feb 2023 21:44:13 +0000 Subject: [PATCH 34/90] Update Esperanto translation --- locales/eo.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/eo.json b/locales/eo.json index 56e718f2..9f37c7cb 100644 --- a/locales/eo.json +++ b/locales/eo.json @@ -476,5 +476,8 @@ "channel_tab_streams_label": "Tujelsendoj", "channel_tab_playlists_label": "Ludlistoj", "channel_tab_channels_label": "Kanaloj", - "channel_tab_shorts_label": "Mallongaj" + "channel_tab_shorts_label": "Mallongaj", + "Music in this video": "Muziko en ĉi tiu video", + "Artist: ": "Artisto: ", + "Album: ": "Albumo: " } From 054686e557b8c1b1aa708c04b5c20552eb0c7b40 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 3 Feb 2023 17:12:10 +0000 Subject: [PATCH 35/90] Update Ukrainian translation --- locales/uk.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/uk.json b/locales/uk.json index ae2fb5bd..b44d237f 100644 --- a/locales/uk.json +++ b/locales/uk.json @@ -492,5 +492,8 @@ "channel_tab_shorts_label": "Shorts", "channel_tab_streams_label": "Прямі трансляції", "channel_tab_playlists_label": "Добірки", - "channel_tab_channels_label": "Канали" + "channel_tab_channels_label": "Канали", + "Music in this video": "Музика в цьому відео", + "Artist: ": "Виконавець: ", + "Album: ": "Альбом: " } From db6d3d2191b5f499ff56b54e7e29d198c159b6d6 Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 3 Feb 2023 09:46:16 +0000 Subject: [PATCH 36/90] Update Chinese (Simplified) translation --- locales/zh-CN.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 385f16bd..aff6dd3e 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -456,5 +456,12 @@ "search_filters_type_option_all": "任意类型", "search_filters_features_option_vr180": "VR180", "Popular enabled: ": "已启用流行度: ", - "error_video_not_in_playlist": "此播放列表中不存在请求的视频。 单击析出查看播放列表主页。" + "error_video_not_in_playlist": "此播放列表中不存在请求的视频。 单击析出查看播放列表主页。", + "Music in this video": "此视频中的音乐", + "channel_tab_playlists_label": "播放列表", + "Artist: ": "艺术家: ", + "channel_tab_streams_label": "直播", + "Album: ": "专辑: ", + "channel_tab_shorts_label": "短视频", + "channel_tab_channels_label": "频道" } From 591f816781cfbf31f761ef6ccf59a1769c002041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Fri, 3 Feb 2023 04:25:29 +0000 Subject: [PATCH 37/90] Update Turkish translation --- locales/tr.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/locales/tr.json b/locales/tr.json index 76cce15a..d98e2038 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -397,8 +397,8 @@ "videoinfo_watch_on_youTube": "YouTube'da İzle", "download_subtitles": "Alt Yazılar - `x` (.vtt)", "preferences_save_player_pos_label": "Oynatma Konumunu Kaydet: ", - "generic_views_count": "{{count}} Görüntüleme", - "generic_views_count_plural": "{{count}} Görüntüleme", + "generic_views_count": "{{count}} Görüntülenme", + "generic_views_count_plural": "{{count}} Görüntülenme", "generic_subscribers_count": "{{count}} Abone", "generic_subscribers_count_plural": "{{count}} Abone", "generic_subscriptions_count": "{{count}} Abonelik", @@ -476,5 +476,8 @@ "channel_tab_channels_label": "Kanallar", "channel_tab_shorts_label": "Kısa Çekimler", "channel_tab_streams_label": "Canlı Yayınlar", - "channel_tab_playlists_label": "Oynatma Listeleri" + "channel_tab_playlists_label": "Oynatma Listeleri", + "Album: ": "Albüm: ", + "Music in this video": "Bu videodaki müzik", + "Artist: ": "Sanatçı: " } From fc5092c3992eba953903d5bf9bd206fc50e0be6b Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 3 Feb 2023 02:09:55 +0000 Subject: [PATCH 38/90] Update Chinese (Traditional) translation --- locales/zh-TW.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 3b51721d..8aa9869a 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -460,5 +460,8 @@ "channel_tab_shorts_label": "短片", "channel_tab_playlists_label": "播放清單", "channel_tab_channels_label": "頻道", - "channel_tab_streams_label": "直播" + "channel_tab_streams_label": "直播", + "Artist: ": "藝術家: ", + "Album: ": "專輯: ", + "Music in this video": "此影片中的音樂" } From 58688a6311205ee7503277d802d9e63eb90f2016 Mon Sep 17 00:00:00 2001 From: maboroshin Date: Sat, 4 Feb 2023 15:10:38 +0000 Subject: [PATCH 39/90] Update Japanese translation --- locales/ja.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ja.json b/locales/ja.json index 9df1477b..3ad4b494 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -460,5 +460,8 @@ "channel_tab_playlists_label": "再生リスト", "error_video_not_in_playlist": "要求された動画はこの再生リスト内に存在しません。再生リストのホームへ。", "channel_tab_shorts_label": "ショート", - "channel_tab_channels_label": "チャンネル" + "channel_tab_channels_label": "チャンネル", + "Music in this video": "この動画の音楽", + "Artist: ": "アーティスト: ", + "Album: ": "アルバム: " } From 256b518469d1c3aa2c73aa5552ffa404d58232c5 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Sun, 5 Feb 2023 20:05:22 +0000 Subject: [PATCH 40/90] Update Croatian translation --- locales/hr.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/hr.json b/locales/hr.json index 7914ab16..72cd6a8e 100644 --- a/locales/hr.json +++ b/locales/hr.json @@ -492,5 +492,8 @@ "channel_tab_streams_label": "Prijenosi uživo", "channel_tab_playlists_label": "Zbirke", "channel_tab_channels_label": "Kanali", - "channel_tab_shorts_label": "Kratka videa" + "channel_tab_shorts_label": "Kratka videa", + "Music in this video": "Glazba u ovom videu", + "Album: ": "Album: ", + "Artist: ": "Izvođač: " } From f2390ed052e018c6b11fdb1f9b356891022bb822 Mon Sep 17 00:00:00 2001 From: Fjuro Date: Fri, 3 Feb 2023 15:39:21 +0000 Subject: [PATCH 41/90] Update Czech translation --- locales/cs.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/cs.json b/locales/cs.json index 7502de0b..51db1550 100644 --- a/locales/cs.json +++ b/locales/cs.json @@ -492,5 +492,8 @@ "channel_tab_shorts_label": "Shorts", "channel_tab_playlists_label": "Playlisty", "channel_tab_channels_label": "Kanály", - "channel_tab_streams_label": "Živé přenosy" + "channel_tab_streams_label": "Živé přenosy", + "Music in this video": "Hudba v tomto videu", + "Artist: ": "Umělec: ", + "Album: ": "Album: " } From 299eb9207bd3dcfc35690ae876aa740d131b7b64 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 3 Feb 2023 13:10:19 +0000 Subject: [PATCH 42/90] Update Albanian translation --- locales/sq.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/locales/sq.json b/locales/sq.json index b8651316..15025750 100644 --- a/locales/sq.json +++ b/locales/sq.json @@ -463,5 +463,10 @@ "search_filters_duration_option_none": "Çfarëdo kohëzgjatjeje", "search_filters_duration_option_medium": "Mesatare (4 - 20 minuta)", "search_filters_features_option_vr180": "VR180", - "search_filters_apply_button": "Apliko filtrat e përzgjedhur" + "search_filters_apply_button": "Apliko filtrat e përzgjedhur", + "channel_tab_playlists_label": "Luajlista", + "Artist: ": "Artist: ", + "Album: ": "Album: ", + "channel_tab_channels_label": "Kanale", + "Music in this video": "Muzikë në këtë video" } From c5d134451140157939043d7be8aa70fad87488f8 Mon Sep 17 00:00:00 2001 From: Damjan Gerl Date: Fri, 3 Feb 2023 09:11:13 +0000 Subject: [PATCH 43/90] Update Slovenian translation --- locales/sl.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/sl.json b/locales/sl.json index 9a4a1bde..47f295e0 100644 --- a/locales/sl.json +++ b/locales/sl.json @@ -508,5 +508,8 @@ "channel_tab_playlists_label": "Seznami predvajanja", "channel_tab_shorts_label": "Kratki videoposnetki", "channel_tab_channels_label": "Kanali", - "channel_tab_streams_label": "Prenosi v živo" + "channel_tab_streams_label": "Prenosi v živo", + "Artist: ": "Umetnik/ca: ", + "Music in this video": "Glasba v tem videoposnetku", + "Album: ": "Album: " } From cb7c4a82200bc5098ed35bd736e54a35b837edc3 Mon Sep 17 00:00:00 2001 From: "Marsel J. Jonker" Date: Thu, 9 Feb 2023 01:41:14 +0100 Subject: [PATCH 44/90] Add Afrikaans translation --- locales/af.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 locales/af.json diff --git a/locales/af.json b/locales/af.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/locales/af.json @@ -0,0 +1 @@ +{} From e4d14481c5f738f86fb45275a341e2c8264cda51 Mon Sep 17 00:00:00 2001 From: SC Date: Thu, 9 Feb 2023 19:42:49 +0000 Subject: [PATCH 45/90] Update Portuguese translation --- locales/pt.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/pt.json b/locales/pt.json index 79a39ab6..b6b6c110 100644 --- a/locales/pt.json +++ b/locales/pt.json @@ -476,5 +476,8 @@ "channel_tab_playlists_label": "Listas de reprodução", "channel_tab_channels_label": "Canais", "channel_tab_shorts_label": "Curtos", - "channel_tab_streams_label": "Diretos" + "channel_tab_streams_label": "Diretos", + "Music in this video": "Música neste vídeo", + "Artist: ": "Artista: ", + "Album: ": "Álbum: " } From 9c400fd455e3282ef3444a8f28ec7943f5d37a7a Mon Sep 17 00:00:00 2001 From: AHOHNMYC Date: Sat, 11 Feb 2023 15:48:41 +0000 Subject: [PATCH 46/90] Update Russian translation --- locales/ru.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/ru.json b/locales/ru.json index 85628d0f..733e0be1 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -492,5 +492,8 @@ "channel_tab_playlists_label": "Плейлисты", "channel_tab_channels_label": "Каналы", "channel_tab_streams_label": "Живое вещание", - "channel_tab_shorts_label": "Shorts" + "channel_tab_shorts_label": "Shorts", + "Music in this video": "Музыка в этом видео", + "Artist: ": "Исполнитель: ", + "Album: ": "Альбом: " } From 8384fa94c2de8c4bf561f4fe5964ce802f22a545 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 14 Feb 2023 22:48:37 -0500 Subject: [PATCH 47/90] Community: Parse polls --- src/invidious/channels/community.cr | 38 ++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index 13af2d8b..a0e79c22 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -185,10 +185,40 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) end end end - # TODO - # when .has_key?("pollRenderer") - # attachment = attachment["pollRenderer"] - # json.field "type", "poll" + when .has_key?("pollRenderer") + attachment = attachment["pollRenderer"] + json.field "type", "poll" + json.field "totalVotes", attachment["totalVotes"]["simpleText"].as_s + json.field "choices" do + json.array do + attachment["choices"].as_a.each do |choice| + json.object do + json.field "text", choice["text"]["runs"][0]["text"].as_s + # A choice can have an image associated with it. + # Ex post: https://www.youtube.com/post/UgkxD4XavXUD4NQiddJXXdohbwOwcVqrH9Re + if choice["image"]? + thumbnail = choice["image"]["thumbnails"][0].as_h + width = thumbnail["width"].as_i + height = thumbnail["height"].as_i + aspect_ratio = (width.to_f / height.to_f) + url = thumbnail["url"].as_s.gsub(/=w\d+-h\d+(-p)?(-nd)?(-df)?(-rwa)?/, "=s640") + qualities = {320, 560, 640, 1280, 2000} + json.field "image" do + json.array do + qualities.each do |quality| + json.object do + json.field "url", url.gsub(/=s\d+/, "=s#{quality}") + json.field "width", quality + json.field "height", (quality / aspect_ratio).ceil.to_i + end + end + end + end + end + end + end + end + end when .has_key?("postMultiImageRenderer") attachment = attachment["postMultiImageRenderer"] json.field "type", "multiImage" From aecbafbc7beb5c007031c02cfba9f419c58d4545 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 14 Feb 2023 22:52:59 -0500 Subject: [PATCH 48/90] Community: parse replyCount --- src/invidious/channels/community.cr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index a0e79c22..9f9f3fde 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -108,6 +108,8 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) like_count = post["actionButtons"]["commentActionButtonsRenderer"]["likeButton"]["toggleButtonRenderer"]["accessibilityData"]["accessibilityData"]["label"] .try &.as_s.gsub(/\D/, "").to_i? || 0 + reply_count = short_text_to_number(post.dig?("actionButtons", "commentActionButtonsRenderer", "replyButton", "buttonRenderer", "text", "simpleText").try &.as_s || "0") + json.field "content", html_to_content(content_html) json.field "contentHtml", content_html @@ -115,6 +117,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) json.field "likeCount", like_count + json.field "replyCount", reply_count json.field "commentId", post["postId"]? || post["commentId"]? || "" json.field "authorIsChannelOwner", post["authorEndpoint"]["browseEndpoint"]["browseId"] == ucid From 4731480821247a542ff05a8faedefcef55c009d9 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 14 Feb 2023 23:03:25 -0500 Subject: [PATCH 49/90] parse votes as number Co-Authored-By: syeopite <70992037+syeopite@users.noreply.github.com> --- src/invidious/channels/community.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index 9f9f3fde..87659c47 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -191,7 +191,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) when .has_key?("pollRenderer") attachment = attachment["pollRenderer"] json.field "type", "poll" - json.field "totalVotes", attachment["totalVotes"]["simpleText"].as_s + json.field "totalVotes", short_text_to_number(attachment["totalVotes"]["simpleText"].as_s.split(" ")[0]) json.field "choices" do json.array do attachment["choices"].as_a.each do |choice| From d03a62641f20a8dfd15fc9fe50373a5e75ee3d6e Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Wed, 15 Feb 2023 00:20:45 -0500 Subject: [PATCH 50/90] Add support for custom emojis in comments --- src/invidious/comments.cr | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 357a461c..5749248e 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -182,7 +182,11 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "contentHtml", content_html json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) - + json.field "isMember", (node_comment["sponsorCommentBadge"]? != nil) + if node_comment["sponsorCommentBadge"]? + # Member icon thumbnails always have one object and there's only ever the url property in it + json.field "memberIconUrl", node_comment["sponsorCommentBadge"]["sponsorCommentBadgeRenderer"]["customBadge"]["thumbnails"][0]["url"].to_s + end json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) @@ -674,6 +678,14 @@ def content_to_comment_html(content, video_id : String? = "") text = "#{text}" if run["bold"]? text = "#{text}" if run["strikethrough"]? text = "#{text}" if run["italics"]? + if emojiImage = run.dig?("emoji", "image") + emojiAlt = emojiImage.dig?("accessibility", "accessibilityData", "label").try &.as_s || text + emojiThumb = emojiImage["thumbnails"][0] + emojiUrl = "/ggpht#{URI.parse(emojiThumb["url"].as_s).request_target}" + emojiWidth = emojiThumb["width"] + emojiHeight = emojiThumb["height"] + text = "\"#{emojiAlt}\"" + end text end From 76ad4e802603f82fe45d522a9c268e972d428a75 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 16 Feb 2023 14:12:56 -0500 Subject: [PATCH 51/90] show member icon, hide deleted emojis, fix non-custom emojis --- locales/en-US.json | 1 + src/invidious/comments.cr | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/locales/en-US.json b/locales/en-US.json index a5c16fd7..5bbf6db6 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -405,6 +405,7 @@ "YouTube comment permalink": "YouTube comment permalink", "permalink": "permalink", "`x` marked it with a ❤": "`x` marked it with a ❤", + "Member": "Member", "Audio mode": "Audio mode", "Video mode": "Video mode", "Playlists": "Playlists", diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 5749248e..f1942ceb 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -328,11 +328,21 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) + member_icon = "" if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool author_name += " " elsif child["verified"]?.try &.as_bool author_name += " " end + if child["isMember"]?.try &.as_bool + member_icon = "\"\"" + end html << <<-END_HTML
@@ -343,6 +353,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) #{author_name} + #{member_icon}

#{child["contentHtml"]}

END_HTML @@ -678,13 +689,17 @@ def content_to_comment_html(content, video_id : String? = "") text = "#{text}" if run["bold"]? text = "#{text}" if run["strikethrough"]? text = "#{text}" if run["italics"]? - if emojiImage = run.dig?("emoji", "image") - emojiAlt = emojiImage.dig?("accessibility", "accessibilityData", "label").try &.as_s || text - emojiThumb = emojiImage["thumbnails"][0] - emojiUrl = "/ggpht#{URI.parse(emojiThumb["url"].as_s).request_target}" - emojiWidth = emojiThumb["width"] - emojiHeight = emojiThumb["height"] - text = "\"#{emojiAlt}\"" + if run["emoji"]? + if run["emoji"]["isCustomEmoji"]?.try &.as_bool + if emojiImage = run.dig?("emoji", "image") + emojiAlt = emojiImage.dig?("accessibility", "accessibilityData", "label").try &.as_s || text + emojiThumb = emojiImage["thumbnails"][0] + text = "\"#{emojiAlt}\"" + else + # Hide deleted channel emoji + text = "" + end + end end text From a95f82e44bfc77ac8fc1b7acd2159d185a4fa637 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Fri, 17 Feb 2023 12:08:05 -0500 Subject: [PATCH 52/90] Add Playlet to "Projects using Invidious" (#3640) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8d668a29..0744ac50 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab, - [Yattee](https://github.com/yattee/yattee): Alternative YouTube frontend for iPhone, iPad, Mac and Apple TV. - [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client. - [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API) +- [Playlet](https://github.com/iBicha/playlet): Unofficial Youtube client for Roku TV ## Liability From bc5d81fe60b324459ac428f4269316bd4cfdc3a1 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Sun, 19 Feb 2023 12:46:46 -0500 Subject: [PATCH 53/90] use string builder to create images change member to sponsor --- locales/en-US.json | 2 +- src/invidious/comments.cr | 36 ++++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/locales/en-US.json b/locales/en-US.json index 5bbf6db6..bd2b9d44 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -405,7 +405,7 @@ "YouTube comment permalink": "YouTube comment permalink", "permalink": "permalink", "`x` marked it with a ❤": "`x` marked it with a ❤", - "Member": "Member", + "Channel Sponsor": "Channel Sponsor", "Audio mode": "Audio mode", "Video mode": "Video mode", "Playlists": "Playlists", diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index f1942ceb..b866b6ef 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -182,10 +182,10 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b json.field "contentHtml", content_html json.field "isPinned", (node_comment["pinnedCommentBadge"]? != nil) - json.field "isMember", (node_comment["sponsorCommentBadge"]? != nil) + json.field "isSponsor", (node_comment["sponsorCommentBadge"]? != nil) if node_comment["sponsorCommentBadge"]? - # Member icon thumbnails always have one object and there's only ever the url property in it - json.field "memberIconUrl", node_comment["sponsorCommentBadge"]["sponsorCommentBadgeRenderer"]["customBadge"]["thumbnails"][0]["url"].to_s + # Sponsor icon thumbnails always have one object and there's only ever the url property in it + json.field "sponsorIconUrl", node_comment.dig("sponsorCommentBadge", "sponsorCommentBadgeRenderer", "customBadge", "thumbnails", 0, "url").to_s end json.field "published", published.to_unix json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale)) @@ -328,20 +328,19 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end author_name = HTML.escape(child["author"].as_s) - member_icon = "" + sponsor_icon = "" if child["verified"]?.try &.as_bool && child["authorIsChannelOwner"]?.try &.as_bool author_name += " " elsif child["verified"]?.try &.as_bool author_name += " " end - if child["isMember"]?.try &.as_bool - member_icon = "\"\"" + if child["isSponsor"].as_bool + sponsor_icon = String.build do |str| + str << %() + end end html << <<-END_HTML
@@ -353,7 +352,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) #{author_name} - #{member_icon} + #{sponsor_icon}

#{child["contentHtml"]}

END_HTML @@ -689,12 +688,21 @@ def content_to_comment_html(content, video_id : String? = "") text = "#{text}" if run["bold"]? text = "#{text}" if run["strikethrough"]? text = "#{text}" if run["italics"]? + + # check for custom emojis if run["emoji"]? if run["emoji"]["isCustomEmoji"]?.try &.as_bool if emojiImage = run.dig?("emoji", "image") emojiAlt = emojiImage.dig?("accessibility", "accessibilityData", "label").try &.as_s || text emojiThumb = emojiImage["thumbnails"][0] - text = "\"#{emojiAlt}\"" + text = String.build do |str| + str << %() << emojiAlt << ') + end else # Hide deleted channel emoji text = "" From b287ddc52acf43c3d3a5fc11e42a8b1b8d66e800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milien=20Devos=20=28perso=29?= Date: Sun, 19 Feb 2023 20:20:47 +0100 Subject: [PATCH 54/90] Allow to set a label for exempting from staling (#3651) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 11168aea..a945da58 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -23,4 +23,4 @@ jobs: stale-pr-label: "stale" ascending: true # Never mark feature requests/enhancements as stale - exempt-issue-labels: "feature-request,enhancement" + exempt-issue-labels: "feature-request,enhancement,exempt-stale" From bde21d527f1fae4a84b964f1b297d7b246526ba0 Mon Sep 17 00:00:00 2001 From: Wes van der Vleuten <16665772+WesVleuten@users.noreply.github.com> Date: Sun, 19 Feb 2023 20:41:18 +0100 Subject: [PATCH 55/90] Fixed console error --- assets/js/watched_indicator.js | 24 +++++++++++++++++++++ assets/js/watched_widget.js | 24 --------------------- src/invidious/views/add_playlist_items.ecr | 2 +- src/invidious/views/channel.ecr | 2 +- src/invidious/views/edit_playlist.ecr | 2 +- src/invidious/views/feeds/playlists.ecr | 2 +- src/invidious/views/feeds/popular.ecr | 2 +- src/invidious/views/feeds/subscriptions.ecr | 3 ++- src/invidious/views/feeds/trending.ecr | 2 +- src/invidious/views/hashtag.ecr | 2 +- src/invidious/views/playlist.ecr | 2 +- src/invidious/views/search.ecr | 2 +- 12 files changed, 35 insertions(+), 34 deletions(-) create mode 100644 assets/js/watched_indicator.js diff --git a/assets/js/watched_indicator.js b/assets/js/watched_indicator.js new file mode 100644 index 00000000..e971cd80 --- /dev/null +++ b/assets/js/watched_indicator.js @@ -0,0 +1,24 @@ +'use strict'; +var save_player_pos_key = 'save_player_pos'; + +function get_all_video_times() { + return helpers.storage.get(save_player_pos_key) || {}; +} + +document.querySelectorAll('.watched-indicator').forEach(function (indicator) { + var watched_part = get_all_video_times()[indicator.dataset.id]; + var total = parseInt(indicator.dataset.length, 10); + if (watched_part === undefined) { + watched_part = total; + } + var percentage = Math.round((watched_part / total) * 100); + + if (percentage < 5) { + percentage = 5; + } + if (percentage > 90) { + percentage = 100; + } + + indicator.style.width = percentage + '%'; +}); diff --git a/assets/js/watched_widget.js b/assets/js/watched_widget.js index 02537111..f1ac9cb4 100644 --- a/assets/js/watched_widget.js +++ b/assets/js/watched_widget.js @@ -32,27 +32,3 @@ function mark_unwatched(target) { } }); } - -var save_player_pos_key = 'save_player_pos'; - -function get_all_video_times() { - return helpers.storage.get(save_player_pos_key) || {}; -} - -document.querySelectorAll('.watched-indicator').forEach(function (indicator) { - var watched_part = get_all_video_times()[indicator.dataset.id]; - var total = parseInt(indicator.dataset.length, 10); - if (watched_part === undefined) { - watched_part = total; - } - var percentage = Math.round((watched_part / total) * 100); - - if (percentage < 5) { - percentage = 5; - } - if (percentage > 90) { - percentage = 100; - } - - indicator.style.width = percentage + '%'; -}); diff --git a/src/invidious/views/add_playlist_items.ecr b/src/invidious/views/add_playlist_items.ecr index 70575de3..bcba74cf 100644 --- a/src/invidious/views/add_playlist_items.ecr +++ b/src/invidious/views/add_playlist_items.ecr @@ -39,7 +39,7 @@ <% end %>
- + <% if query %> <%- query_encoded = URI.encode_www_form(query.text, space_to_plus: true) -%> diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index 931dd407..6e62a471 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -49,7 +49,7 @@ <% end %>
- +
diff --git a/src/invidious/views/edit_playlist.ecr b/src/invidious/views/edit_playlist.ecr index 100764c7..548104c8 100644 --- a/src/invidious/views/edit_playlist.ecr +++ b/src/invidious/views/edit_playlist.ecr @@ -62,7 +62,7 @@ <% end %>
- +
diff --git a/src/invidious/views/feeds/playlists.ecr b/src/invidious/views/feeds/playlists.ecr index f9064762..e52a7707 100644 --- a/src/invidious/views/feeds/playlists.ecr +++ b/src/invidious/views/feeds/playlists.ecr @@ -33,4 +33,4 @@ <% end %>
- + diff --git a/src/invidious/views/feeds/popular.ecr b/src/invidious/views/feeds/popular.ecr index 919002cd..5fbe539c 100644 --- a/src/invidious/views/feeds/popular.ecr +++ b/src/invidious/views/feeds/popular.ecr @@ -17,4 +17,4 @@ <% end %>
- + diff --git a/src/invidious/views/feeds/subscriptions.ecr b/src/invidious/views/feeds/subscriptions.ecr index d4e93240..9c69c5b0 100644 --- a/src/invidious/views/feeds/subscriptions.ecr +++ b/src/invidious/views/feeds/subscriptions.ecr @@ -54,6 +54,7 @@ }.to_pretty_json %> +
<% videos.each do |item| %> @@ -61,7 +62,7 @@ <% end %>
- +
diff --git a/src/invidious/views/feeds/trending.ecr b/src/invidious/views/feeds/trending.ecr index 76218165..7dc416c6 100644 --- a/src/invidious/views/feeds/trending.ecr +++ b/src/invidious/views/feeds/trending.ecr @@ -46,4 +46,4 @@ <% end %>
- + diff --git a/src/invidious/views/hashtag.ecr b/src/invidious/views/hashtag.ecr index 6064af74..3351c21c 100644 --- a/src/invidious/views/hashtag.ecr +++ b/src/invidious/views/hashtag.ecr @@ -24,7 +24,7 @@ <%- end -%>
- +
diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr index 1df047ba..a04acf4c 100644 --- a/src/invidious/views/playlist.ecr +++ b/src/invidious/views/playlist.ecr @@ -106,7 +106,7 @@ <% end %>
- +
diff --git a/src/invidious/views/search.ecr b/src/invidious/views/search.ecr index c4960d08..a7469e36 100644 --- a/src/invidious/views/search.ecr +++ b/src/invidious/views/search.ecr @@ -37,7 +37,7 @@
<%- end -%> - +
From b5eb6016bbc455921ce3d8ec24589d706f8a5fb1 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Sun, 19 Feb 2023 14:51:39 -0500 Subject: [PATCH 56/90] add spaces at end of attribute --- src/invidious/comments.cr | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index b866b6ef..6c323bc1 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -336,10 +336,10 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) end if child["isSponsor"].as_bool sponsor_icon = String.build do |str| - str << %() + str << %() end end html << <<-END_HTML @@ -696,12 +696,12 @@ def content_to_comment_html(content, video_id : String? = "") emojiAlt = emojiImage.dig?("accessibility", "accessibilityData", "label").try &.as_s || text emojiThumb = emojiImage["thumbnails"][0] text = String.build do |str| - str << %() << emojiAlt << ') + str << %() << emojiAlt << ) end else # Hide deleted channel emoji From 8046316f200801e2e8c34ce2d43da6a16fb86fe8 Mon Sep 17 00:00:00 2001 From: Raman Date: Tue, 14 Feb 2023 07:26:13 +0000 Subject: [PATCH 57/90] Update Hindi translation --- locales/hi.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/locales/hi.json b/locales/hi.json index e576080f..54e0fe84 100644 --- a/locales/hi.json +++ b/locales/hi.json @@ -470,5 +470,7 @@ "crash_page_switch_instance": "किसी दूसरे उदाहरण का इस्तेमाल करें", "crash_page_read_the_faq": "अक्सर पूछे जाने वाले प्रश्न (FAQ) पढ़ें", "crash_page_refresh": "पृष्ठ को एक बार साफ़ करें", - "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें" + "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें", + "Popular enabled: ": "लोकप्रिय सक्षम: ", + "Artist: ": "कलाकार: " } From 64780ce1da79ce5ea7f1619b46cb9e7137c4cc97 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 17 Feb 2023 20:47:00 +0000 Subject: [PATCH 58/90] Update Russian translation --- locales/ru.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/locales/ru.json b/locales/ru.json index 733e0be1..7ca5cf1f 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -69,11 +69,11 @@ "preferences_vr_mode_label": "Интерактивные 360-градусные видео (необходим WebGL): ", "preferences_category_visual": "Настройки сайта", "preferences_player_style_label": "Стиль проигрывателя: ", - "Dark mode: ": "Тёмное оформление: ", + "Dark mode: ": "Темное оформление: ", "preferences_dark_mode_label": "Тема: ", - "dark": "тёмная", + "dark": "темная", "light": "светлая", - "preferences_thin_mode_label": "Облегчённое оформление: ", + "preferences_thin_mode_label": "Облегченное оформление: ", "preferences_category_misc": "Прочие настройки", "preferences_automatic_instance_redirect_label": "Автоматическая смена зеркала (переход на redirect.invidious.io): ", "preferences_category_subscription": "Настройки подписок", @@ -88,7 +88,7 @@ "channel name": "по названию канала", "channel name - reverse": "по названию канала в обратном порядке", "Only show latest video from channel: ": "Показывать только последние видео с каналов: ", - "Only show latest unwatched video from channel: ": "Показывать только непросмотренные видео с каналов: ", + "Only show latest unwatched video from channel: ": "Показывать только последние непросмотренные видео с канала: ", "preferences_unseen_only_label": "Показывать только непросмотренные видео: ", "preferences_notifications_only_label": "Показывать только оповещения, если они есть: ", "Enable web notifications": "Включить уведомления в браузере", @@ -147,13 +147,13 @@ "License: ": "Лицензия: ", "Family friendly? ": "Семейный просмотр: ", "Wilson score: ": "Оценка Уилсона: ", - "Engagement: ": "Вовлечённость: ", + "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.": "Похоже, у вас отключён JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Похоже, у вас отключен JavaScript. Нажмите сюда, чтобы увидеть комментарии. Но учтите: они могут загружаться немного медленнее.", "View YouTube comments": "Показать комментарии с YouTube", "View more comments on Reddit": "Посмотреть больше комментариев на Reddit", "View `x` comments": { @@ -180,23 +180,23 @@ "Please log in": "Пожалуйста, войдите", "Invidious Private Feed for `x`": "Приватная лента Invidious для `x`", "channel:`x`": "канал: `x`", - "Deleted or invalid channel": "Канал удалён или не найден", + "Deleted or invalid channel": "Канал удален или не найден", "This channel does not exist.": "Такого канала не существует.", - "Could not get channel info.": "Не удаётся получить информацию об этом канале.", - "Could not fetch comments": "Не удаётся загрузить комментарии", + "Could not get channel info.": "Не удается получить информацию об этом канале.", + "Could not fetch comments": "Не удается загрузить комментарии", "`x` ago": "`x` назад", - "Load more": "Загрузить ещё", + "Load more": "Загрузить еще", "Could not create mix.": "Не удалось создать микс.", "Empty playlist": "Плейлист пуст", - "Not a playlist.": "Некорректный плейлист.", + "Not a playlist.": "Это не плейлист.", "Playlist does not exist.": "Плейлист не существует.", - "Could not pull trending pages.": "Не удаётся загрузить страницы «в тренде».", + "Could not pull trending pages.": "Не удается загрузить страницы «в тренде».", "Hidden field \"challenge\" is a required field": "Необходимо заполнить скрытое поле «challenge»", "Hidden field \"token\" is a required field": "Необходимо заполнить скрытое поле «токен»", "Erroneous challenge": "Неправильный ответ в «challenge»", "Erroneous token": "Неправильный токен", "No such user": "Пользователь не найден", - "Token is expired, please try again": "Срок действия токена истёк, попробуйте позже", + "Token is expired, please try again": "Срок действия токена истек, попробуйте позже", "English": "Английский", "English (auto-generated)": "Английский (созданы автоматически)", "Afrikaans": "Африкаанс", @@ -453,8 +453,8 @@ "Portuguese (Brazil)": "Португальский (Бразилия)", "footer_source_code": "Исходный код", "footer_original_source_code": "Оригинальный исходный код", - "footer_modfied_source_code": "Изменённый исходный код", - "user_saved_playlists": "`x` сохранённых плейлистов", + "footer_modfied_source_code": "Измененный исходный код", + "user_saved_playlists": "`x` сохраненных плейлистов", "crash_page_search_issue": "поискали похожую проблему на GitHub", "comments_points_count_0": "{{count}} плюс", "comments_points_count_1": "{{count}} плюса", From 7b124eec640ca601d2cafc366867e1d6cd283577 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Mon, 20 Feb 2023 16:27:16 -0500 Subject: [PATCH 59/90] Add History API --- src/invidious/routes/api/v1/authenticated.cr | 50 ++++++++++++++++++++ src/invidious/routing.cr | 5 ++ 2 files changed, 55 insertions(+) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index 6b935312..e670a87c 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -54,6 +54,56 @@ module Invidious::Routes::API::V1::Authenticated env.response.status_code = 204 end + def self.get_history(env) + env.response.content_type = "application/json" + user = env.get("user").as(User) + + page = env.params.query["page"]?.try &.to_i? + page ||= 1 + + max_results = env.params.query["max_results"]?.try &.to_i?.try &.clamp(0, MAX_ITEMS_PER_PAGE) + max_results ||= user.preferences.max_results + max_results ||= CONFIG.default_user_preferences.max_results + + if user.watched[(page - 1) * max_results]? + watched = user.watched.reverse[(page - 1) * max_results, max_results] + end + watched ||= [] of String + + return watched.to_json + end + + def self.mark_watched(env) + user = env.get("user").as(User) + + id = env.params.url["id"]?.try &.as(String) + if !id + return error_json(400, "Invalid video id.") + end + + Invidious::Database::Users.mark_watched(user, id) + env.response.status_code = 204 + end + + def self.mark_unwatched(env) + user = env.get("user").as(User) + + id = env.params.url["id"]?.try &.as(String) + if !id + return error_json(400, "Invalid video id.") + end + + Invidious::Database::Users.mark_unwatched(user, id) + env.response.status_code = 204 + end + + def self.clear_history(env) + user = env.get("user").as(User) + + Invidious::Database::Users.clear_watch_history(user) + env.response.status_code = 204 + end + def self.feed(env) env.response.content_type = "application/json" diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr index dca2f117..9e2ade3d 100644 --- a/src/invidious/routing.cr +++ b/src/invidious/routing.cr @@ -257,6 +257,11 @@ module Invidious::Routing get "/api/v1/auth/export/invidious", {{namespace}}::Authenticated, :export_invidious post "/api/v1/auth/import/invidious", {{namespace}}::Authenticated, :import_invidious + get "/api/v1/auth/history", {{namespace}}::Authenticated, :get_history + post "/api/v1/auth/history/:id", {{namespace}}::Authenticated, :mark_watched + delete "/api/v1/auth/history/:id", {{namespace}}::Authenticated, :mark_unwatched + delete "/api/v1/auth/history", {{namespace}}::Authenticated, :clear_history + get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions From 15e9510ab212ac1f8b6bc2a5a3e83ebc4ba1fe90 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Mon, 20 Feb 2023 16:43:36 -0500 Subject: [PATCH 60/90] Check preferences before marking video as watched --- src/invidious/routes/api/v1/authenticated.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index e670a87c..dc86bb3c 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -76,6 +76,10 @@ module Invidious::Routes::API::V1::Authenticated def self.mark_watched(env) user = env.get("user").as(User) + if !user.preferences.watch_history + return error_json(409, "Watch history is disabled in preferences.") + end + id = env.params.url["id"]?.try &.as(String) if !id return error_json(400, "Invalid video id.") From 6ee51f460a27618d5926e9caf230a7ada2823e70 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Tue, 21 Feb 2023 15:24:25 -0500 Subject: [PATCH 61/90] encode username on callback --- src/invidious/routes/account.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/routes/account.cr b/src/invidious/routes/account.cr index d01aee56..284d5b06 100644 --- a/src/invidious/routes/account.cr +++ b/src/invidious/routes/account.cr @@ -262,7 +262,7 @@ module Invidious::Routes::Account end query["token"] = access_token - query["username"] = user.email + query["username"] = URI.encode_path_segment(user.email) url.query = query.to_s env.redirect url.to_s From 57e4312d9fabf4dc284426c74db952c3609f9987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Marcelo=20Alvarenga?= Date: Mon, 20 Feb 2023 22:56:13 +0000 Subject: [PATCH 62/90] Update Portuguese (Brazil) translation --- locales/pt-BR.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index afd31ede..079c4ea1 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -476,5 +476,8 @@ "channel_tab_channels_label": "Canais", "channel_tab_playlists_label": "Listas de reprodução", "channel_tab_shorts_label": "Curtos", - "channel_tab_streams_label": "Ao Vivo" + "channel_tab_streams_label": "Ao Vivo", + "Music in this video": "Música neste vídeo", + "Artist: ": "Artista: ", + "Album: ": "Álbum: " } From 596a16c085c6e3afd998273ab3c9bff3c109e07c Mon Sep 17 00:00:00 2001 From: ssantos Date: Mon, 20 Feb 2023 14:05:29 +0000 Subject: [PATCH 63/90] Update Portuguese (Portugal) translation --- locales/pt-PT.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/pt-PT.json b/locales/pt-PT.json index 1788deb1..43834d70 100644 --- a/locales/pt-PT.json +++ b/locales/pt-PT.json @@ -472,5 +472,12 @@ "search_message_change_filters_or_query": "Tente alargar os termos genéricos da pesquisa e/ou alterar os filtros.", "crash_page_refresh": "tentou recarregar a página", "crash_page_switch_instance": "tentou usar outra instância", - "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução." + "error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. Clique aqui para a página inicial da lista de reprodução.", + "Artist: ": "Artista: ", + "Album: ": "Álbum: ", + "channel_tab_streams_label": "Diretos", + "channel_tab_playlists_label": "Listas de reprodução", + "channel_tab_channels_label": "Canais", + "Music in this video": "Música neste vídeo", + "channel_tab_shorts_label": "Curtos" } From 7e0210d090b0b6141832944bba19ca9fe1170817 Mon Sep 17 00:00:00 2001 From: Saurmandal Date: Mon, 20 Feb 2023 15:39:25 +0000 Subject: [PATCH 64/90] Update Hindi translation --- locales/hi.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/hi.json b/locales/hi.json index 54e0fe84..41335266 100644 --- a/locales/hi.json +++ b/locales/hi.json @@ -472,5 +472,12 @@ "crash_page_refresh": "पृष्ठ को एक बार साफ़ करें", "crash_page_search_issue": "GitHub पर मौजूदा मुद्दे ढूँढ़ें", "Popular enabled: ": "लोकप्रिय सक्षम: ", - "Artist: ": "कलाकार: " + "Artist: ": "कलाकार: ", + "Music in this video": "इस वीडियो में संगीत", + "Album: ": "एल्बम: ", + "error_video_not_in_playlist": "अनुरोधित वीडियो इस प्लेलिस्ट में मौजूद नहीं है। प्लेलिस्ट के मुखपृष्ठ पर जाने के लिए यहाँ क्लिक करें।", + "channel_tab_shorts_label": "शॉर्ट्स", + "channel_tab_streams_label": "लाइवस्ट्रीम्स", + "channel_tab_playlists_label": "प्लेलिस्ट्स", + "channel_tab_channels_label": "चैनल्स" } From 3ddcfea8faea4d6a6e4db9c52b2c54eb07625d75 Mon Sep 17 00:00:00 2001 From: Ashirg-ch Date: Thu, 23 Feb 2023 15:25:03 +0000 Subject: [PATCH 65/90] Update English (United States) translation --- 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 a5c16fd7..86b83a23 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -454,7 +454,7 @@ "footer_documentation": "Documentation", "footer_source_code": "Source code", "footer_original_source_code": "Original source code", - "footer_modfied_source_code": "Modified Source code", + "footer_modfied_source_code": "Modified source code", "adminprefs_modified_source_code_url_label": "URL to modified source code repository", "none": "none", "videoinfo_started_streaming_x_ago": "Started streaming `x` ago", From 23f1f8bde3ae838c26871eae16b1b3fbf37e11de Mon Sep 17 00:00:00 2001 From: Ashirg-ch Date: Thu, 23 Feb 2023 15:17:43 +0000 Subject: [PATCH 66/90] Update German translation --- locales/de.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/de.json b/locales/de.json index 55c40905..c2941d6d 100644 --- a/locales/de.json +++ b/locales/de.json @@ -472,5 +472,12 @@ "search_filters_duration_option_none": "Beliebige Länge", "search_filters_date_label": "Upload-Datum", "search_filters_date_option_none": "Beliebiges Datum", - "error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen." + "error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen.", + "channel_tab_shorts_label": "Shorts", + "channel_tab_streams_label": "Livestreams", + "Music in this video": "Musik in diesem Video", + "Artist: ": "Künstler: ", + "Album: ": "Album: ", + "channel_tab_playlists_label": "Wiedergabelisten", + "channel_tab_channels_label": "Kanäle" } From eb3af9d4f101a5b99d26fe81b28d1789de3b4d7c Mon Sep 17 00:00:00 2001 From: gallegonovato Date: Thu, 23 Feb 2023 17:29:11 +0000 Subject: [PATCH 67/90] Update Spanish translation --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index 6cf721f3..fec3a667 100644 --- a/locales/es.json +++ b/locales/es.json @@ -364,7 +364,7 @@ "footer_original_source_code": "Código fuente original", "adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", "footer_source_code": "Código fuente", - "footer_modfied_source_code": "Código fuente modificado", + "footer_modfied_source_code": "Modificación del código fuente", "footer_donate_page": "Donar", "preferences_region_label": "País del contenido: ", "preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", From 0efb56238f9e75ca2d083cbd5c5701333b0bcd92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Sun, 26 Feb 2023 18:53:33 +0000 Subject: [PATCH 68/90] Update Turkish translation --- locales/tr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/tr.json b/locales/tr.json index d98e2038..b7cb3958 100644 --- a/locales/tr.json +++ b/locales/tr.json @@ -363,7 +363,7 @@ "footer_documentation": "Belgelendirme", "footer_source_code": "Kaynak Kodları", "footer_original_source_code": "Orijinal Kaynak Kodları", - "footer_modfied_source_code": "Değiştirilmiş Kaynak Kodları", + "footer_modfied_source_code": "Değiştirilmiş kaynak kodları", "adminprefs_modified_source_code_url_label": "Değiştirilmiş Kaynak Kodları Deposunun URL'si", "footer_donate_page": "Bağış Yap", "preferences_region_label": "İçerik Ülkesi: ", From 24ac873532bb562398d64afbd9e8f6cf943d283c Mon Sep 17 00:00:00 2001 From: maboroshin Date: Fri, 24 Feb 2023 05:24:09 +0000 Subject: [PATCH 69/90] Update Japanese translation --- locales/ja.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/ja.json b/locales/ja.json index 3ad4b494..d08413ea 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -5,7 +5,7 @@ "generic_subscribers_count_0": "{{count}} 人の登録者", "generic_subscriptions_count_0": "{{count}} 個の登録チャンネル", "LIVE": "ライブ", - "Shared `x` ago": "`x`前に共有", + "Shared `x` ago": "`x`前に公開", "Unsubscribe": "登録解除", "Subscribe": "登録", "View channel on YouTube": "YouTube でチャンネルを見る", @@ -56,17 +56,17 @@ "preferences_category_player": "プレイヤーの設定", "preferences_video_loop_label": "常にループ: ", "preferences_autoplay_label": "自動再生: ", - "preferences_continue_label": "デフォルトで次を再生: ", + "preferences_continue_label": "次の動画を再生: ", "preferences_continue_autoplay_label": "次の動画を自動再生: ", "preferences_listen_label": "デフォルトで音声モードを使用: ", - "preferences_local_label": "動画をプロキシーに通す: ", - "preferences_speed_label": "デフォルトの再生速度: ", + "preferences_local_label": "動画視聴にプロキシーを経由: ", + "preferences_speed_label": "標準の再生速度: ", "preferences_quality_label": "優先する画質: ", "preferences_volume_label": "プレイヤーの音量: ", "preferences_comments_label": "デフォルトのコメント: ", "youtube": "YouTube", "reddit": "Reddit", - "preferences_captions_label": "デフォルトの字幕: ", + "preferences_captions_label": "優先する字幕: ", "Fallback captions: ": "フォールバック時の字幕: ", "preferences_related_videos_label": "関連動画を表示: ", "preferences_annotations_label": "デフォルトでアノテーションを表示: ", @@ -108,7 +108,7 @@ "Watch history": "再生履歴", "Delete account": "アカウントを削除", "preferences_category_admin": "管理者設定", - "preferences_default_home_label": "デフォルトのホーム: ", + "preferences_default_home_label": "ホームに表示するページ: ", "preferences_feed_menu_label": "フィードメニュー: ", "preferences_show_nick_label": "ニックネームを一番上に表示する: ", "Top enabled: ": "トップページを有効化: ", @@ -157,7 +157,7 @@ "Engagement: ": "エンゲージメント: ", "Whitelisted regions: ": "ホワイトリストの地域: ", "Blacklisted regions: ": "ブラックリストの地域: ", - "Shared `x`": "`x`に共有", + "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.": "やあ!君は JavaScript を無効にしているのかな?ここをクリックしてコメントを見れるけど、読み込みには少し時間がかかることがあるのを覚えておいてね。", @@ -191,9 +191,9 @@ "This channel does not exist.": "このチャンネルは存在しません。", "Could not get channel info.": "チャンネル情報を取得できませんでした。", "Could not fetch comments": "コメントを取得できませんでした", - "comments_view_x_replies_0": "{{count}} 件の返信を見る", + "comments_view_x_replies_0": "{{count}}件の返信を表示", "`x` ago": "`x`前", - "Load more": "もっと読み込む", + "Load more": "もっと見る", "comments_points_count_0": "{{count}}点", "Could not create mix.": "ミックスを作成できませんでした。", "Empty playlist": "空の再生リスト", @@ -377,8 +377,8 @@ "search_filters_duration_option_short": "4 分未満", "footer_documentation": "文書", "footer_source_code": "ソースコード", - "footer_original_source_code": "ソースコード (元)", - "footer_modfied_source_code": "ソースコード (改変)", + "footer_original_source_code": "元のソースコード", + "footer_modfied_source_code": "改変して使用", "adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL", "search_filters_duration_option_long": "20 分以上", "preferences_region_label": "地域: ", From fdf162e318ac3dd6c38e64a47938944efc730824 Mon Sep 17 00:00:00 2001 From: Milo Ivir Date: Sat, 25 Feb 2023 19:16:10 +0000 Subject: [PATCH 70/90] Update Croatian translation --- locales/hr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/hr.json b/locales/hr.json index 72cd6a8e..c626ed28 100644 --- a/locales/hr.json +++ b/locales/hr.json @@ -359,13 +359,13 @@ "next_steps_error_message_refresh": "Aktualiziraj stranicu", "next_steps_error_message_go_to_youtube": "Idi na YouTube", "footer_donate_page": "Doniraj", - "adminprefs_modified_source_code_url_label": "URL do repozitorija izmijenjenog izvornog koda", + "adminprefs_modified_source_code_url_label": "URL do repozitorija prilagođenog izvornog koda", "search_filters_duration_option_short": "Kratko (< 4 minute)", "search_filters_duration_option_long": "Dugo (> 20 minute)", "footer_source_code": "Izvorni kod", - "footer_modfied_source_code": "Izmijenjeni izvorni kod", + "footer_modfied_source_code": "Prilagođen izvorni kod", "footer_documentation": "Dokumentacija", - "footer_original_source_code": "Izvoran izvorni kod", + "footer_original_source_code": "Prvobitan izvorni kod", "preferences_region_label": "Zemlja sadržaja: ", "preferences_quality_dash_label": "Preferirana DASH videokvaliteta: ", "preferences_quality_option_dash": "DASH (adaptativna kvaliteta)", From 2974ed348cbb429ee780affa077c25d08d189995 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Thu, 23 Feb 2023 18:03:55 +0000 Subject: [PATCH 71/90] Update Albanian translation --- locales/sq.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/locales/sq.json b/locales/sq.json index 15025750..7f29a035 100644 --- a/locales/sq.json +++ b/locales/sq.json @@ -286,7 +286,7 @@ "search_filters_type_option_show": "Shfaqe", "search_filters_duration_option_short": "E shkurtër (< 4 minuta)", "search_filters_features_option_purchased": "Të blera", - "footer_modfied_source_code": "Kod Burim i ndryshuar", + "footer_modfied_source_code": "Kod burim i ndryshuar", "adminprefs_modified_source_code_url_label": "URL e depos së ndryshuar të kodit burim", "none": "asnjë", "videoinfo_started_streaming_x_ago": "Filloi transmetimin `x` më parë", @@ -468,5 +468,7 @@ "Artist: ": "Artist: ", "Album: ": "Album: ", "channel_tab_channels_label": "Kanale", - "Music in this video": "Muzikë në këtë video" + "Music in this video": "Muzikë në këtë video", + "channel_tab_shorts_label": "Të shkurtra", + "channel_tab_streams_label": "Transmetime të drejtpërdrejta" } From 27bf4d02a185e6750cdecdc4f1c169b0723dbbf5 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Wed, 1 Mar 2023 22:08:19 -0500 Subject: [PATCH 72/90] PR nursing --- src/invidious/routes/api/v1/authenticated.cr | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index dc86bb3c..a20d23d0 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -58,15 +58,16 @@ module Invidious::Routes::API::V1::Authenticated env.response.content_type = "application/json" user = env.get("user").as(User) - page = env.params.query["page"]?.try &.to_i? + page = env.params.query["page"]?.try &.to_i?.try &.clamp(0, Int32::MAX) page ||= 1 max_results = env.params.query["max_results"]?.try &.to_i?.try &.clamp(0, MAX_ITEMS_PER_PAGE) max_results ||= user.preferences.max_results max_results ||= CONFIG.default_user_preferences.max_results - if user.watched[(page - 1) * max_results]? - watched = user.watched.reverse[(page - 1) * max_results, max_results] + start_index = (page - 1) * max_results + if user.watched[start_index]? + watched = user.watched.reverse[start_index, max_results] end watched ||= [] of String From 4a1471346237f44481b4de823e87d393739e12c1 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Wed, 1 Mar 2023 23:39:07 -0500 Subject: [PATCH 73/90] use dig, create private image quality constant Co-Authored-By: Samantaz Fox --- src/invidious/channels/community.cr | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr index 87659c47..da8be6ea 100644 --- a/src/invidious/channels/community.cr +++ b/src/invidious/channels/community.cr @@ -1,3 +1,5 @@ +private IMAGE_QUALITIES = {320, 560, 640, 1280, 2000} + # TODO: Add "sort_by" def fetch_channel_community(ucid, continuation, locale, format, thin_mode) response = YT_POOL.client &.get("/channel/#{ucid}/community?gl=US&hl=en") @@ -75,10 +77,9 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) json.field "author", author json.field "authorThumbnails" do json.array do - qualities = {32, 48, 76, 100, 176, 512} author_thumbnail = post["authorThumbnail"]["thumbnails"].as_a[0]["url"].as_s - qualities.each do |quality| + IMAGE_QUALITIES.each do |quality| json.object do json.field "url", author_thumbnail.gsub(/s\d+-/, "s#{quality}-") json.field "width", quality @@ -177,9 +178,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) aspect_ratio = (width.to_f / height.to_f) url = thumbnail["url"].as_s.gsub(/=w\d+-h\d+(-p)?(-nd)?(-df)?(-rwa)?/, "=s640") - qualities = {320, 560, 640, 1280, 2000} - - qualities.each do |quality| + IMAGE_QUALITIES.each do |quality| json.object do json.field "url", url.gsub(/=s\d+/, "=s#{quality}") json.field "width", quality @@ -196,7 +195,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) json.array do attachment["choices"].as_a.each do |choice| json.object do - json.field "text", choice["text"]["runs"][0]["text"].as_s + json.field "text", choice.dig("text", "runs", 0, "text").as_s # A choice can have an image associated with it. # Ex post: https://www.youtube.com/post/UgkxD4XavXUD4NQiddJXXdohbwOwcVqrH9Re if choice["image"]? @@ -205,10 +204,9 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) height = thumbnail["height"].as_i aspect_ratio = (width.to_f / height.to_f) url = thumbnail["url"].as_s.gsub(/=w\d+-h\d+(-p)?(-nd)?(-df)?(-rwa)?/, "=s640") - qualities = {320, 560, 640, 1280, 2000} json.field "image" do json.array do - qualities.each do |quality| + IMAGE_QUALITIES.each do |quality| json.object do json.field "url", url.gsub(/=s\d+/, "=s#{quality}") json.field "width", quality @@ -235,9 +233,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode) aspect_ratio = (width.to_f / height.to_f) url = thumbnail["url"].as_s.gsub(/=w\d+-h\d+(-p)?(-nd)?(-df)?(-rwa)?/, "=s640") - qualities = {320, 560, 640, 1280, 2000} - - qualities.each do |quality| + IMAGE_QUALITIES.each do |quality| json.object do json.field "url", url.gsub(/=s\d+/, "=s#{quality}") json.field "width", quality From 406d74d0b6c85f300b7a96f85acb0963c998f944 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Wed, 1 Mar 2023 21:09:00 +0000 Subject: [PATCH 74/90] Update Spanish translation --- locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/es.json b/locales/es.json index fec3a667..6cf721f3 100644 --- a/locales/es.json +++ b/locales/es.json @@ -364,7 +364,7 @@ "footer_original_source_code": "Código fuente original", "adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", "footer_source_code": "Código fuente", - "footer_modfied_source_code": "Modificación del código fuente", + "footer_modfied_source_code": "Código fuente modificado", "footer_donate_page": "Donar", "preferences_region_label": "País del contenido: ", "preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", From 60b7c8015c9ae77664d0b0680a81cfcc979d5a03 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Thu, 2 Mar 2023 07:29:44 -0500 Subject: [PATCH 75/90] add channel emoji css class --- assets/css/default.css | 4 ++++ src/invidious/comments.cr | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/css/default.css b/assets/css/default.css index 9788e9f7..5ec79a43 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -565,3 +565,7 @@ p, /* Wider settings name to less word wrap */ .pure-form-aligned .pure-control-group label { width: 19em; } + +.channel-emoji { + margin: 0 2px; +} diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 6c323bc1..56622dec 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -701,7 +701,7 @@ def content_to_comment_html(content, video_id : String? = "") str << %(title=") << emojiAlt << "\" " str << %(width=") << emojiThumb["width"] << "\" " str << %(height=") << emojiThumb["height"] << "\" " - str << %(style="margin-right:2px;margin-left:2px;"/>) + str << %(class="channel-emoji"/>) end else # Hide deleted channel emoji From 8c0efb3ea9e409796ae860128b16d8aac860c5c6 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Mar 2023 14:45:26 -0500 Subject: [PATCH 76/90] validate video id --- src/invidious/routes/api/v1/authenticated.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index a20d23d0..75dad6df 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -94,7 +94,7 @@ module Invidious::Routes::API::V1::Authenticated user = env.get("user").as(User) id = env.params.url["id"]?.try &.as(String) - if !id + if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end From 38f6d08be6559915262cd246b7a82988700250a5 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Mar 2023 14:47:14 -0500 Subject: [PATCH 77/90] Validate id, avoid db call if not needed --- src/invidious/routes/api/v1/authenticated.cr | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index 75dad6df..e8e7c524 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -82,7 +82,7 @@ module Invidious::Routes::API::V1::Authenticated end id = env.params.url["id"]?.try &.as(String) - if !id + if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end @@ -93,6 +93,10 @@ module Invidious::Routes::API::V1::Authenticated def self.mark_unwatched(env) user = env.get("user").as(User) + if !user.preferences.watch_history + return error_json(409, "Watch history is disabled in preferences.") + end + id = env.params.url["id"]?.try &.as(String) if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") From a5cc66e060578f801371fe3f4b53bcb3d61b3ef9 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Thu, 2 Mar 2023 16:11:50 -0500 Subject: [PATCH 78/90] Fix id check --- src/invidious/routes/api/v1/authenticated.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index e8e7c524..a024736c 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -81,7 +81,7 @@ module Invidious::Routes::API::V1::Authenticated return error_json(409, "Watch history is disabled in preferences.") end - id = env.params.url["id"]?.try &.as(String) + id = env.params.url["id"] if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end @@ -97,7 +97,7 @@ module Invidious::Routes::API::V1::Authenticated return error_json(409, "Watch history is disabled in preferences.") end - id = env.params.url["id"]?.try &.as(String) + id = env.params.url["id"] if !id.match(/[a-zA-Z0-9_-]{11}/) return error_json(400, "Invalid video id.") end From 03542f2f5dcf7686b8d5fd38bb0c8c0e9e4a2cb7 Mon Sep 17 00:00:00 2001 From: amogusussy <83502633+amogusussy@users.noreply.github.com> Date: Fri, 3 Mar 2023 22:28:26 +0000 Subject: [PATCH 79/90] Fix empty description boxes. If a video has no description, (without this commit) the description box will still take up 8.3em, even if there's no content in it. This fixes that issue. --- 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 3deaebe1..24910610 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -515,7 +515,7 @@ hr { #descexpansionbutton ~ div { overflow: hidden; - height: 8.3em; + max-height: 8.3em; } #descexpansionbutton:checked ~ div { From a3ecd46b019637b9a9d926d91042bbf3603c7f7c Mon Sep 17 00:00:00 2001 From: Paul Fauchon Date: Sun, 5 Mar 2023 04:55:27 +0800 Subject: [PATCH 80/90] add new Android client to list of projects using invidious --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0744ac50..abf57e38 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,7 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab, - [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client. - [Ytfzf](https://github.com/pystardust/ytfzf): A posix script to find and watch youtube videos from the terminal. (Without API) - [Playlet](https://github.com/iBicha/playlet): Unofficial Youtube client for Roku TV +- [Clipious](https://github.com/lamarios/clipious): Unofficial Invidious client for Android ## Liability From 3c3d9ebf84f6dbac671dd7561b72de4af45f1747 Mon Sep 17 00:00:00 2001 From: fresh Date: Sat, 4 Mar 2023 23:07:28 +0000 Subject: [PATCH 81/90] Update Greek translation --- locales/el.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/el.json b/locales/el.json index 3448a4dc..8d0c84dd 100644 --- a/locales/el.json +++ b/locales/el.json @@ -366,7 +366,7 @@ "preferences_quality_option_hd720": "HD720", "preferences_quality_option_medium": "Μεσαία", "preferences_quality_option_small": "Μικρό", - "preferences_quality_option_dash": "DASH (προσαρμοστική ποιότητα)", + "preferences_quality_option_dash": "DASH (προσαρμόσιμη ποιότητα)", "preferences_quality_dash_option_4320p": "4320p", "preferences_quality_dash_option_720p": "720p", "invidious": "Invidious", @@ -450,5 +450,5 @@ "search_filters_type_option_show": "Μπάρα προόδου διαβάσματος", "preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: ", "search_filters_title": "Φίλτρο", - "search_message_no_results": "Δεν" + "search_message_no_results": "Δε βρέθηκαν αποτελέσματα." } From 1f607273a87c85e65c7bfc7345984c6b7d631a5a Mon Sep 17 00:00:00 2001 From: Felipe Nogueira Date: Sun, 5 Mar 2023 02:24:43 +0000 Subject: [PATCH 82/90] Update Portuguese (Brazil) translation --- locales/pt-BR.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/pt-BR.json b/locales/pt-BR.json index 079c4ea1..ec00d46e 100644 --- a/locales/pt-BR.json +++ b/locales/pt-BR.json @@ -381,7 +381,7 @@ "footer_documentation": "Documentação", "footer_source_code": "Código fonte", "footer_original_source_code": "Código fonte original", - "footer_modfied_source_code": "Código Fonte Modificado", + "footer_modfied_source_code": "Código-fonte modificado", "preferences_quality_dash_label": "Qualidade de vídeo do painel preferida: ", "preferences_region_label": "País do conteúdo: ", "preferences_quality_dash_option_4320p": "4320p", From 9325fa79ae3ee751b52da95997cc4824742531e7 Mon Sep 17 00:00:00 2001 From: VisualPlugin Date: Mon, 6 Mar 2023 06:17:50 +0000 Subject: [PATCH 83/90] Update es.json --- locales/es.json | 106 ++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/locales/es.json b/locales/es.json index 6cf721f3..a0d16325 100644 --- a/locales/es.json +++ b/locales/es.json @@ -52,21 +52,21 @@ "preferences_video_loop_label": "Repetir siempre: ", "preferences_autoplay_label": "Reproducción automática: ", "preferences_continue_label": "Reproducir siguiente por defecto: ", - "preferences_continue_autoplay_label": "Reproducir automáticamente el vídeo siguiente: ", + "preferences_continue_autoplay_label": "Reproducir automáticamente el video siguiente: ", "preferences_listen_label": "Activar el sonido por defecto: ", - "preferences_local_label": "¿Usar un proxy para los vídeos? ", + "preferences_local_label": "¿Usar un proxy para los videos? ", "preferences_speed_label": "Velocidad por defecto: ", - "preferences_quality_label": "Calidad de vídeo preferida: ", + "preferences_quality_label": "Calidad de video preferida: ", "preferences_volume_label": "Volumen del reproductor: ", "preferences_comments_label": "Comentarios por defecto: ", "youtube": "YouTube", "reddit": "Reddit", "preferences_captions_label": "Subtítulos por defecto: ", "Fallback captions: ": "Subtítulos alternativos: ", - "preferences_related_videos_label": "¿Mostrar vídeos relacionados? ", + "preferences_related_videos_label": "¿Mostrar videos relacionados? ", "preferences_annotations_label": "¿Mostrar anotaciones por defecto? ", - "preferences_extend_desc_label": "Extender automáticamente la descripción del vídeo: ", - "preferences_vr_mode_label": "Vídeos interactivos de 360 grados (necesita WebGL): ", + "preferences_extend_desc_label": "Extender automáticamente la descripción del video: ", + "preferences_vr_mode_label": "Videos interactivos de 360 grados (necesita WebGL): ", "preferences_category_visual": "Preferencias visuales", "preferences_player_style_label": "Estilo de reproductor: ", "Dark mode: ": "Modo oscuro: ", @@ -79,16 +79,16 @@ "preferences_category_subscription": "Preferencias de la suscripción", "preferences_annotations_subscribed_label": "¿Mostrar anotaciones por defecto para los canales suscritos? ", "Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ", - "preferences_max_results_label": "Número de vídeos mostrados en la fuente: ", - "preferences_sort_label": "Ordenar los vídeos por: ", + "preferences_max_results_label": "Número de videos mostrados en la fuente: ", + "preferences_sort_label": "Ordenar los videos por: ", "published": "fecha de publicación", "published - reverse": "fecha de publicación: orden inverso", "alphabetically": "alfabéticamente", "alphabetically - reverse": "alfabéticamente: orden inverso", "channel name": "nombre del canal", "channel name - reverse": "nombre del canal: orden inverso", - "Only show latest video from channel: ": "Mostrar solo el último vídeo del canal: ", - "Only show latest unwatched video from channel: ": "Mostrar solo el último vídeo sin ver del canal: ", + "Only show latest video from channel: ": "Mostrar solo el último video del canal: ", + "Only show latest unwatched video from channel: ": "Mostrar solo el último video sin ver del canal: ", "preferences_unseen_only_label": "Mostrar solo los no vistos: ", "preferences_notifications_only_label": "Mostrar solo notificaciones (si hay alguna): ", "Enable web notifications": "Habilitar notificaciones web", @@ -139,7 +139,7 @@ "Editing playlist `x`": "Editando la lista de reproducción 'x'", "Show more": "Mostrar más", "Show less": "Mostrar menos", - "Watch on YouTube": "Ver el vídeo en YouTube", + "Watch on YouTube": "Ver en YouTube", "Switch Invidious Instance": "Cambiar Instancia de Invidious", "Hide annotations": "Ocultar anotaciones", "Show annotations": "Mostrar anotaciones", @@ -153,7 +153,7 @@ "Shared `x`": "Compartido `x`", "Premieres in `x`": "Se estrena en `x`", "Premieres `x`": "Estrenos `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.": "¡Hola! Parece que tiene JavaScript desactivado. Haga clic aquí para ver los comentarios, pero tenga en cuenta que pueden tardar un poco más en cargarse.", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "¡Hola! Parece que tienes JavaScript desactivado. Haz clic aquí para ver los comentarios, pero tengas en cuenta que pueden tardar un poco más en cargarse.", "View YouTube comments": "Ver los comentarios de YouTube", "View more comments on Reddit": "Ver más comentarios en Reddit", "View `x` comments": { @@ -164,7 +164,7 @@ "Hide replies": "Ocultar las respuestas", "Show replies": "Mostrar las respuestas", "Incorrect password": "Contraseña incorrecta", - "Quota exceeded, try again in a few hours": "Cuota excedida, pruebe otra vez en unas horas", + "Quota exceeded, try again in a few hours": "Cuota excedida, prueba otra vez en unas horas", "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "No se puede iniciar sesión, asegúrese de que la autentificación de dos factores (autentificador o SMS) esté habilitada.", "Invalid TFA code": "Código TFA no válido", "Login failed. This may be because two-factor authentication is not turned on for your account.": "Error de inicio de sesion. Puede deberse a que la autentificación de dos factores no está habilitada en su cuenta.", @@ -176,7 +176,7 @@ "Wrong username or password": "Nombre o contraseña incorrecto", "Please sign in using 'Log in with Google'": "Inicie sesión con «Iniciar sesión con Google»", "Password cannot be empty": "La contraseña no puede estar en blanco", - "Password cannot be longer than 55 characters": "La contraseña no puede tener más de 55 caracteres", + "Password cannot be longer than 55 characters": "La contraseña no debe tener más de 55 caracteres", "Please log in": "Inicie sesión, por favor", "Invidious Private Feed for `x`": "Fuente privada de Invidious para `x`", "channel:`x`": "canal: `x`", @@ -198,7 +198,7 @@ "No such user": "Usuario no existe", "Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo", "English": "Inglés", - "English (auto-generated)": "Inglés (generados automáticamente)", + "English (auto-generated)": "Inglés (generado automáticamente)", "Afrikaans": "Afrikáans", "Albanian": "Albanés", "Amharic": "Amárico", @@ -324,50 +324,51 @@ "permalink": "enlace permanente", "`x` marked it with a ❤": "`x` lo ha marcado con un ❤", "Audio mode": "Modo de audio", - "Video mode": "Modo de vídeo", - "channel_tab_videos_label": "Vídeos", + "Video mode": "Modo de video", + "channel_tab_videos_label": "Videos", "Playlists": "Listas de reproducción", "channel_tab_community_label": "Comunidad", - "search_filters_sort_option_relevance": "relevancia", - "search_filters_sort_option_rating": "valoración", - "search_filters_sort_option_date": "fecha", - "search_filters_sort_option_views": "visualizaciones", - "search_filters_type_label": "content_type", + "search_filters_sort_option_relevance": "Relevancia", + "search_filters_sort_option_rating": "Valoración", + "search_filters_sort_option_date": "Fecha de subida", + "search_filters_sort_option_views": "Visualizaciones", + "search_filters_type_label": "tipo de contenido", "search_filters_duration_label": "duración", "search_filters_features_label": "funcionalidades", "search_filters_sort_label": "ordenar", - "search_filters_date_option_hour": "hora", - "search_filters_date_option_today": "hoy", - "search_filters_date_option_week": "semana", - "search_filters_date_option_month": "mes", - "search_filters_date_option_year": "año", - "search_filters_type_option_video": "vídeo", - "search_filters_type_option_channel": "canal", - "search_filters_type_option_playlist": "lista de reproducción", - "search_filters_type_option_movie": "película", - "search_filters_type_option_show": "programa", - "search_filters_features_option_hd": "hd", - "search_filters_features_option_subtitles": "subtítulos", - "search_filters_features_option_c_commons": "creative_commons", - "search_filters_features_option_three_d": "3d", - "search_filters_features_option_live": "directo", - "search_filters_features_option_four_k": "4k", - "search_filters_features_option_location": "ubicación", - "search_filters_features_option_hdr": "hdr", + "search_filters_date_option_hour": "Última hora", + "search_filters_date_option_today": "Hoy", + "search_filters_date_option_week": "Esta semana", + "search_filters_date_option_month": "Este mes", + "search_filters_date_option_year": "Este año", + "search_filters_type_option_video": "Video", + "search_filters_type_option_channel": "Canal", + "search_filters_type_option_playlist": "Lista de reproducción", + "search_filters_type_option_movie": "Película", + "search_filters_type_option_show": "Programa", + "search_filters_features_option_hd": "HD", + "search_filters_features_option_subtitles": "Subtítulos", + "search_filters_features_option_c_commons": "Creative Commons", + "search_filters_features_option_three_d": "3D", + "search_filters_features_option_live": "En directo", + "search_filters_features_option_four_k": "4K", + "search_filters_features_option_location": "Ubicación", + "search_filters_features_option_hdr": "HDR", "Current version: ": "Versión actual: ", "next_steps_error_message": "Después de lo cual debes intentar: ", "next_steps_error_message_refresh": "Recargar la página", "next_steps_error_message_go_to_youtube": "Ir a YouTube", - "search_filters_duration_option_short": "Corto (< 4 minutos)", - "search_filters_duration_option_long": "Largo (> 20 minutos)", + "search_filters_duration_option_short": "Menos de 4 minutos", + "search_filters_duration_option_medium": "De 4 a 20 minutos", + "search_filters_duration_option_long": "Más de 20 minutos", "footer_documentation": "Documentación", "footer_original_source_code": "Código fuente original", - "adminprefs_modified_source_code_url_label": "URL al repositorio de código fuente modificado", + "adminprefs_modified_source_code_url_label": "Enlace al repositorio de código fuente modificado", "footer_source_code": "Código fuente", "footer_modfied_source_code": "Código fuente modificado", "footer_donate_page": "Donar", "preferences_region_label": "País del contenido: ", - "preferences_quality_dash_label": "Calidad de vídeo DASH preferida: ", + "preferences_quality_dash_label": "Calidad de video DASH preferida: ", "preferences_quality_option_hd720": "HD720", "preferences_quality_option_medium": "Intermedia", "preferences_quality_dash_option_auto": "Automática", @@ -376,7 +377,7 @@ "download_subtitles": "Subtítulos- `x` (.vtt)", "user_created_playlists": "`x` listas de reproducción creadas", "user_saved_playlists": "`x` listas de reproducción guardadas", - "Video unavailable": "Vídeo no disponible", + "Video unavailable": "Video no disponible", "videoinfo_youTube_embed_link": "Insertar", "preferences_quality_dash_option_2160p": "2160p", "preferences_quality_dash_option_4320p": "4320p", @@ -413,8 +414,8 @@ "generic_count_weeks_plural": "{{count}} semanas", "generic_playlists_count": "{{count}} lista de reproducción", "generic_playlists_count_plural": "{{count}} listas de reproducción", - "generic_videos_count": "{{count}} vídeo", - "generic_videos_count_plural": "{{count}} vídeos", + "generic_videos_count": "{{count}} video", + "generic_videos_count_plural": "{{count}} videos", "generic_count_months": "{{count}} mes", "generic_count_months_plural": "{{count}} meses", "comments_points_count": "{{count}} punto", @@ -433,7 +434,7 @@ "crash_page_search_issue": "buscado problemas existentes en GitHub", "crash_page_you_found_a_bug": "¡Parece que has encontrado un error en Invidious!", "crash_page_refresh": "probado a recargar la página", - "crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, abre una nueva incidencia en GitHub (preferiblemente en inglés) e incluye el siguiente texto en tu mensaje (NO traduzcas este texto):", + "crash_page_report_issue": "Si nada de lo anterior ha sido de ayuda, por favor, abre una nueva incidencia en GitHub (preferiblemente en inglés) e incluye verbatim el siguiente texto en tu mensaje:", "English (United States)": "Inglés (Estados Unidos)", "Cantonese (Hong Kong)": "Cantonés (Hong Kong)", "Dutch (auto-generated)": "Neerlandés (generados automáticamente)", @@ -461,23 +462,22 @@ "search_message_no_results": "No se han encontrado resultados.", "search_message_change_filters_or_query": "Pruebe ampliar la consulta de búsqueda y/o a cambiar los filtros.", "search_filters_title": "Filtros", - "search_filters_date_label": "Fecha de subida", + "search_filters_date_label": "fecha de subida", "search_filters_date_option_none": "Cualquier fecha", "search_filters_type_option_all": "Cualquier tipo", "search_filters_duration_option_none": "Cualquier duración", "search_filters_features_option_vr180": "VR180", - "search_filters_apply_button": "Aplicar filtros seleccionados", + "search_filters_apply_button": "Aplicar filtros", "tokens_count": "{{count}} ficha", "tokens_count_plural": "{{count}} fichas", "search_message_use_another_instance": " También puede buscar en otra instancia.", - "search_filters_duration_option_medium": "Medio (4 - 20 minutes)", "Popular enabled: ": "¿Habilitar la sección popular? ", - "error_video_not_in_playlist": "El vídeo solicitado no existe en esta lista de reproducción. Haga clic aquí para acceder a la página de inicio de la lista de reproducción.", + "error_video_not_in_playlist": "El video que solicitaste no existe en esta lista de reproducción. Haz clic aquí para acceder a la página de inicio de la lista de reproducción.", "channel_tab_streams_label": "Directos", "channel_tab_channels_label": "Canales", "channel_tab_shorts_label": "Cortos", "channel_tab_playlists_label": "Listas de reproducción", - "Music in this video": "Música en este vídeo", + "Music in this video": "Música en este video", "Artist: ": "Artista: ", "Album: ": "Álbum: " } From 548a0f26ef07a4f2beec3f5e7b7d2b667b9ff50e Mon Sep 17 00:00:00 2001 From: maboroshin Date: Sun, 5 Mar 2023 23:53:05 +0000 Subject: [PATCH 84/90] Update Japanese translation --- locales/ja.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ja.json b/locales/ja.json index d08413ea..4d2ed5a0 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -366,7 +366,7 @@ "search_filters_features_option_subtitles": "字幕", "search_filters_features_option_c_commons": "クリエイティブ・コモンズ", "search_filters_features_option_three_d": "3D", - "search_filters_features_option_live": "生配信", + "search_filters_features_option_live": "ライブ", "search_filters_features_option_four_k": "4K", "search_filters_features_option_location": "場所", "search_filters_features_option_hdr": "HDR", From d8e23d34b63b8f4f34da5c6b4bddf6eb46a3a828 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Mar 2023 11:38:09 -0500 Subject: [PATCH 85/90] add song title for music tracks --- locales/en-US.json | 1 + src/invidious/jsonify/api_v1/video_json.cr | 15 +++++++++++++++ src/invidious/videos.cr | 2 +- src/invidious/videos/music.cr | 3 ++- src/invidious/videos/parser.cr | 5 ++++- src/invidious/views/watch.ecr | 7 ++++--- 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/locales/en-US.json b/locales/en-US.json index 86b83a23..65a81ab7 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -190,6 +190,7 @@ "Blacklisted regions: ": "Blacklisted regions: ", "Music in this video": "Music in this video", "Artist: ": "Artist: ", + "Song: ": "Song: ", "Album: ": "Album: ", "Shared `x`": "Shared `x`", "Premieres in `x`": "Premieres in `x`", diff --git a/src/invidious/jsonify/api_v1/video_json.cr b/src/invidious/jsonify/api_v1/video_json.cr index a2b1a35c..fe4b5223 100644 --- a/src/invidious/jsonify/api_v1/video_json.cr +++ b/src/invidious/jsonify/api_v1/video_json.cr @@ -197,6 +197,21 @@ module Invidious::JSONify::APIv1 end end + if !video.music.empty? + json.field "musicTracks" do + json.array do + video.music.each do |music| + json.object do + json.field "song", music.song + json.field "artist", music.artist + json.field "album", music.album + json.field "license", music.license + end + end + end + end + end + json.field "recommendedVideos" do json.array do video.related_videos.each do |rv| diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 436ac82d..86f5ada4 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -249,7 +249,7 @@ struct Video def music : Array(VideoMusic) info["music"].as_a.map { |music_json| - VideoMusic.new(music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s) + VideoMusic.new(music_json["song"].as_s, music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s) } end diff --git a/src/invidious/videos/music.cr b/src/invidious/videos/music.cr index 402ae46f..08d88a3e 100644 --- a/src/invidious/videos/music.cr +++ b/src/invidious/videos/music.cr @@ -3,10 +3,11 @@ require "json" struct VideoMusic include JSON::Serializable + property song : String property album : String property artist : String property license : String - def initialize(@album : String, @artist : String, @license : String) + def initialize(@song : String, @album : String, @artist : String, @license : String) end end diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index cf43f1be..1a8c25e4 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -322,6 +322,7 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any music_desclist.try &.as_a.each do |music_desc| artist = nil + song = nil album = nil music_license = nil @@ -329,13 +330,15 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any desc_title = extract_text(desc.dig?("infoRowRenderer", "title")) if desc_title == "ARTIST" artist = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) + elsif desc_title == "SONG" + song = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) elsif desc_title == "ALBUM" album = extract_text(desc.dig?("infoRowRenderer", "defaultMetadata")) elsif desc_title == "LICENSES" music_license = extract_text(desc.dig?("infoRowRenderer", "expandedMetadata")) end end - music_list << VideoMusic.new(album.to_s, artist.to_s, music_license.to_s) + music_list << VideoMusic.new(song.to_s, album.to_s, artist.to_s, music_license.to_s) end # Author infos diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 666eb3b0..01b30f7a 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -248,9 +248,10 @@ we're going to need to do it here in order to allow for translations.
<% video.music.each do |music| %>
-

<%= translate(locale, "Artist: ") %><%= music.artist %>

-

<%= translate(locale, "Album: ") %><%= music.album %>

-

<%= translate(locale, "License: ") %><%= music.license %>

+

<%= translate(locale, "Song: ") %><%= music.song %>

+

<%= translate(locale, "Artist: ") %><%= music.artist %>

+

<%= translate(locale, "Album: ") %><%= music.album %>

+

<%= translate(locale, "License: ") %><%= music.license %>

<% end %>
From 742c951bc9fdc6eb1e5687104e67500fb778e0ea Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Mar 2023 13:06:15 -0500 Subject: [PATCH 86/90] support videos with multiple songs --- src/invidious/videos/parser.cr | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 1a8c25e4..722c90e8 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -322,10 +322,17 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any music_desclist.try &.as_a.each do |music_desc| artist = nil - song = nil album = nil music_license = nil + # used when multiple songs + song = music_desc.dig?("carouselLockupRenderer", "videoLockup", "compactVideoRenderer", "title", "simpleText") + + # used when multiple songs and the song has a link + if !song + song = music_desc.dig("carouselLockupRenderer", "videoLockup", "compactVideoRenderer", "title", "runs", 0, "text") + end + music_desc.dig?("carouselLockupRenderer", "infoRows").try &.as_a.each do |desc| desc_title = extract_text(desc.dig?("infoRowRenderer", "title")) if desc_title == "ARTIST" From 0b17f68ebacdb54e74116cf3364c8229e896eff0 Mon Sep 17 00:00:00 2001 From: Brahim Hadriche Date: Tue, 7 Mar 2023 13:50:02 -0500 Subject: [PATCH 87/90] Fix input validation --- src/invidious/routes/api/v1/authenticated.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr index a024736c..ce2ee812 100644 --- a/src/invidious/routes/api/v1/authenticated.cr +++ b/src/invidious/routes/api/v1/authenticated.cr @@ -82,7 +82,7 @@ module Invidious::Routes::API::V1::Authenticated end id = env.params.url["id"] - if !id.match(/[a-zA-Z0-9_-]{11}/) + if !id.match(/^[a-zA-Z0-9_-]{11}$/) return error_json(400, "Invalid video id.") end @@ -98,7 +98,7 @@ module Invidious::Routes::API::V1::Authenticated end id = env.params.url["id"] - if !id.match(/[a-zA-Z0-9_-]{11}/) + if !id.match(/^[a-zA-Z0-9_-]{11}$/) return error_json(400, "Invalid video id.") end From e3081ef1a93973fe10ba8508ad31d257d641350e Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Mar 2023 14:23:08 -0500 Subject: [PATCH 88/90] Apply style change suggestions Co-authored-by: Samantaz Fox --- src/invidious/videos.cr | 7 ++++++- src/invidious/videos/parser.cr | 10 ++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 86f5ada4..0038a97a 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -249,7 +249,12 @@ struct Video def music : Array(VideoMusic) info["music"].as_a.map { |music_json| - VideoMusic.new(music_json["song"].as_s, music_json["album"].as_s, music_json["artist"].as_s, music_json["license"].as_s) + VideoMusic.new( + music_json["song"].as_s, + music_json["album"].as_s, + music_json["artist"].as_s, + music_json["license"].as_s + ) } end diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 722c90e8..7cfc7ea7 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -325,12 +325,10 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any album = nil music_license = nil - # used when multiple songs - song = music_desc.dig?("carouselLockupRenderer", "videoLockup", "compactVideoRenderer", "title", "simpleText") - - # used when multiple songs and the song has a link - if !song - song = music_desc.dig("carouselLockupRenderer", "videoLockup", "compactVideoRenderer", "title", "runs", 0, "text") + # Used when the video has multiple songs + if song_title = music_desc.dig?("carouselLockupRenderer", "videoLockup", "compactVideoRenderer", "title") + # "simpleText" for plain text / "runs" when song has a link + song = song_title["simpleText"]? || song_title.dig("runs", 0, "text") end music_desc.dig?("carouselLockupRenderer", "infoRows").try &.as_a.each do |desc| From a781cf37347e97c469eb098e95c9a80482aac1b9 Mon Sep 17 00:00:00 2001 From: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:59:51 -0500 Subject: [PATCH 89/90] readd try as bool for isSponsor key --- src/invidious/comments.cr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 56622dec..b15d63d4 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -334,7 +334,8 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) elsif child["verified"]?.try &.as_bool author_name += " " end - if child["isSponsor"].as_bool + + if child["isSponsor"]?.try &.as_bool sponsor_icon = String.build do |str| str << %( Date: Sun, 12 Mar 2023 18:50:01 -0400 Subject: [PATCH 90/90] remove music license --- src/invidious/views/watch.ecr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 01b30f7a..ce92a546 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -251,7 +251,6 @@ we're going to need to do it here in order to allow for translations.

<%= translate(locale, "Song: ") %><%= music.song %>

<%= translate(locale, "Artist: ") %><%= music.artist %>

<%= translate(locale, "Album: ") %><%= music.album %>

-

<%= translate(locale, "License: ") %><%= music.license %>

<% end %>