From ec8fe21485ea446f2e76f12b234842dc6c7ab513 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Sat, 30 Jan 2021 10:53:25 +0100 Subject: [PATCH 01/35] Add issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 31 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 23 +++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..534e943c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + + + + +**Describe the bug** + + +**Steps to Reproduce** + + +**Logs** + + +**Screenshots** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..690b6a8d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + + + + +**Is your feature request related to a problem? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + From e7ada61881ffe408dd47919b810f58e15ecea755 Mon Sep 17 00:00:00 2001 From: Alexander Pushkov Date: Sat, 30 Jan 2021 23:45:55 +0000 Subject: [PATCH 02/35] Add link[rel="alternate"] pointing to YouTube version --- src/invidious/views/watch.ecr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 786a88b6..21740b06 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -22,6 +22,7 @@ + <%= rendered "components/player_sources" %> <%= HTML.escape(video.title) %> - Invidious <% end %> From b30db728cc8435b3debbaa27aad940fe482683ac Mon Sep 17 00:00:00 2001 From: Perflyst Date: Sun, 31 Jan 2021 13:17:50 +0100 Subject: [PATCH 03/35] Add suggestions --- .github/ISSUE_TEMPLATE/bug_report.md | 12 ++++++++---- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 534e943c..8b83cbe5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- name: Bug report -about: Create a report to help us improve -title: '' +about: Create a report to help us improve Invidious +title: '[Bug] ' labels: bug assignees: '' @@ -9,6 +9,7 @@ assignees: '' + **Describe the bug** @@ -22,10 +23,13 @@ assignees: '' --> **Logs** - + **Screenshots** **Additional context** - + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 690b6a8d..b308eb0d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,7 +1,7 @@ --- name: Feature request about: Suggest an idea for this project -title: '' +title: '[Feature request] ' labels: enhancement assignees: '' From 991a04dc2aeb08f497f004cfe82ec9b5a4be72e3 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Tue, 2 Feb 2021 06:18:16 +0100 Subject: [PATCH 04/35] Adjust routes Simple routes have been moved into a single `Misc` file. Embed routes have been moved into a single `Embed` file. The preferences route has been renamed to be more consistent with other parts of the codebase. --- src/invidious.cr | 16 +++++------ .../routes/{embed/show.cr => embed.cr} | 28 +++++++++++++++++-- src/invidious/routes/embed/index.cr | 25 ----------------- src/invidious/routes/licenses.cr | 6 ---- src/invidious/routes/{home.cr => misc.cr} | 14 ++++++++-- .../{user_preferences.cr => preferences.cr} | 2 +- src/invidious/routes/privacy.cr | 6 ---- 7 files changed, 47 insertions(+), 50 deletions(-) rename src/invidious/routes/{embed/show.cr => embed.cr} (87%) delete mode 100644 src/invidious/routes/embed/index.cr delete mode 100644 src/invidious/routes/licenses.cr rename src/invidious/routes/{home.cr => misc.cr} (65%) rename src/invidious/routes/{user_preferences.cr => preferences.cr} (99%) delete mode 100644 src/invidious/routes/privacy.cr diff --git a/src/invidious.cr b/src/invidious.cr index 713d193e..a63d6aca 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -311,12 +311,12 @@ before_all do |env| env.set "current_page", URI.encode_www_form(current_page) end -Invidious::Routing.get "/", Invidious::Routes::Home -Invidious::Routing.get "/privacy", Invidious::Routes::Privacy -Invidious::Routing.get "/licenses", Invidious::Routes::Licenses +Invidious::Routing.get "/", Invidious::Routes::Misc, :home +Invidious::Routing.get "/privacy", Invidious::Routes::Misc, :privacy +Invidious::Routing.get "/licenses", Invidious::Routes::Misc, :licenses Invidious::Routing.get "/watch", Invidious::Routes::Watch -Invidious::Routing.get "/embed/", Invidious::Routes::Embed::Index -Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed::Show +Invidious::Routing.get "/embed/", Invidious::Routes::Embed, :redirect +Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed, :show Invidious::Routing.get "/view_all_playlists", Invidious::Routes::Playlists, :index Invidious::Routing.get "/create_playlist", Invidious::Routes::Playlists, :new Invidious::Routing.post "/create_playlist", Invidious::Routes::Playlists, :create @@ -335,9 +335,9 @@ Invidious::Routing.get "/search", Invidious::Routes::Search, :search Invidious::Routing.get "/login", Invidious::Routes::Login, :login_page Invidious::Routing.post "/login", Invidious::Routes::Login, :login Invidious::Routing.post "/signout", Invidious::Routes::Login, :signout -Invidious::Routing.get "/preferences", Invidious::Routes::UserPreferences, :show -Invidious::Routing.post "/preferences", Invidious::Routes::UserPreferences, :update -Invidious::Routing.get "/toggle_theme", Invidious::Routes::UserPreferences, :toggle_theme +Invidious::Routing.get "/preferences", Invidious::Routes::PreferencesRoute, :show +Invidious::Routing.post "/preferences", Invidious::Routes::PreferencesRoute, :update +Invidious::Routing.get "/toggle_theme", Invidious::Routes::PreferencesRoute, :toggle_theme # Users diff --git a/src/invidious/routes/embed/show.cr b/src/invidious/routes/embed.cr similarity index 87% rename from src/invidious/routes/embed/show.cr rename to src/invidious/routes/embed.cr index 8a655556..4fd265c9 100644 --- a/src/invidious/routes/embed/show.cr +++ b/src/invidious/routes/embed.cr @@ -1,5 +1,29 @@ -class Invidious::Routes::Embed::Show < Invidious::Routes::BaseRoute - def handle(env) +class Invidious::Routes::Embed < Invidious::Routes::BaseRoute + def redirect(env) + locale = LOCALES[env.get("preferences").as(Preferences).locale]? + + if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "") + begin + playlist = get_playlist(PG_DB, plid, locale: locale) + offset = env.params.query["index"]?.try &.to_i? || 0 + videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale) + rescue ex + return error_template(500, ex) + end + + url = "/embed/#{videos[0].id}?#{env.params.query}" + + if env.params.query.size > 0 + url += "?#{env.params.query}" + end + else + url = "/" + end + + env.redirect url + end + + def show(env) locale = LOCALES[env.get("preferences").as(Preferences).locale]? id = env.params.url["id"] diff --git a/src/invidious/routes/embed/index.cr b/src/invidious/routes/embed/index.cr deleted file mode 100644 index 32a4966b..00000000 --- a/src/invidious/routes/embed/index.cr +++ /dev/null @@ -1,25 +0,0 @@ -class Invidious::Routes::Embed::Index < Invidious::Routes::BaseRoute - def handle(env) - locale = LOCALES[env.get("preferences").as(Preferences).locale]? - - if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "") - begin - playlist = get_playlist(PG_DB, plid, locale: locale) - offset = env.params.query["index"]?.try &.to_i? || 0 - videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale) - rescue ex - return error_template(500, ex) - end - - url = "/embed/#{videos[0].id}?#{env.params.query}" - - if env.params.query.size > 0 - url += "?#{env.params.query}" - end - else - url = "/" - end - - env.redirect url - end -end diff --git a/src/invidious/routes/licenses.cr b/src/invidious/routes/licenses.cr deleted file mode 100644 index 38fde7bb..00000000 --- a/src/invidious/routes/licenses.cr +++ /dev/null @@ -1,6 +0,0 @@ -class Invidious::Routes::Licenses < Invidious::Routes::BaseRoute - def handle(env) - locale = LOCALES[env.get("preferences").as(Preferences).locale]? - rendered "licenses" - end -end diff --git a/src/invidious/routes/home.cr b/src/invidious/routes/misc.cr similarity index 65% rename from src/invidious/routes/home.cr rename to src/invidious/routes/misc.cr index 486a7344..bc009633 100644 --- a/src/invidious/routes/home.cr +++ b/src/invidious/routes/misc.cr @@ -1,5 +1,5 @@ -class Invidious::Routes::Home < Invidious::Routes::BaseRoute - def handle(env) +class Invidious::Routes::Misc < Invidious::Routes::BaseRoute + def home(env) preferences = env.get("preferences").as(Preferences) locale = LOCALES[preferences.locale]? user = env.get? "user" @@ -25,4 +25,14 @@ class Invidious::Routes::Home < Invidious::Routes::BaseRoute templated "empty" end end + + def privacy(env) + locale = LOCALES[env.get("preferences").as(Preferences).locale]? + templated "privacy" + end + + def licenses(env) + locale = LOCALES[env.get("preferences").as(Preferences).locale]? + rendered "licenses" + end end diff --git a/src/invidious/routes/user_preferences.cr b/src/invidious/routes/preferences.cr similarity index 99% rename from src/invidious/routes/user_preferences.cr rename to src/invidious/routes/preferences.cr index a689a2a2..4901d22b 100644 --- a/src/invidious/routes/user_preferences.cr +++ b/src/invidious/routes/preferences.cr @@ -1,4 +1,4 @@ -class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute +class Invidious::Routes::PreferencesRoute < Invidious::Routes::BaseRoute def show(env) locale = LOCALES[env.get("preferences").as(Preferences).locale]? diff --git a/src/invidious/routes/privacy.cr b/src/invidious/routes/privacy.cr deleted file mode 100644 index 4565c94c..00000000 --- a/src/invidious/routes/privacy.cr +++ /dev/null @@ -1,6 +0,0 @@ -class Invidious::Routes::Privacy < Invidious::Routes::BaseRoute - def handle(env) - locale = LOCALES[env.get("preferences").as(Preferences).locale]? - templated "privacy" - end -end From 5f03a583d19868555c1dabe200b5b7022eb6d74f Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sun, 31 Jan 2021 19:52:32 +0100 Subject: [PATCH 05/35] Update code for Crystal 0.36.0 Rename `HTTPClient@socket` to `HTTPClient@io`, see https://github.com/crystal-lang/crystal/pull/9543. Rename `URI#full_path` to `URI#request_target`, see https://github.com/crystal-lang/crystal/pull/10099. --- src/invidious.cr | 30 +++++++++++------------ src/invidious/comments.cr | 10 ++++---- src/invidious/helpers/proxy.cr | 6 ++--- src/invidious/helpers/utils.cr | 2 +- src/invidious/jobs/bypass_captcha_job.cr | 2 +- src/invidious/routes/embed.cr | 4 +-- src/invidious/routes/login.cr | 2 +- src/invidious/routes/watch.cr | 4 +-- src/invidious/views/channel.ecr | 4 +-- src/invidious/views/community.ecr | 4 +-- src/invidious/views/components/item.ecr | 6 ++--- src/invidious/views/components/player.ecr | 2 +- src/invidious/views/playlists.ecr | 4 +-- src/invidious/views/watch.ecr | 2 +- 14 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/invidious.cr b/src/invidious.cr index a63d6aca..ec6df302 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -1428,9 +1428,9 @@ get "/feed/playlist/:plid" do |env| node.attributes.each do |attribute| case attribute.name when "url", "href" - full_path = URI.parse(node[attribute.name]).full_path - query_string_opt = full_path.starts_with?("/watch?v=") ? "&#{params}" : "" - node[attribute.name] = "#{HOST_URL}#{full_path}#{query_string_opt}" + request_target = URI.parse(node[attribute.name]).request_target + query_string_opt = request_target.starts_with?("/watch?v=") ? "&#{params}" : "" + node[attribute.name] = "#{HOST_URL}#{request_target}#{query_string_opt}" else nil # Skip end end @@ -1439,7 +1439,7 @@ get "/feed/playlist/:plid" do |env| document = document.to_xml(options: XML::SaveOptions::NO_DECL) document.scan(/(?[^<]+)<\/uri>/).each do |match| - content = "#{HOST_URL}#{URI.parse(match["url"]).full_path}" + content = "#{HOST_URL}#{URI.parse(match["url"]).request_target}" document = document.gsub(match[0], "#{content}") end @@ -1634,7 +1634,7 @@ end get "/attribution_link" do |env| if query = env.params.query["u"]? - url = URI.parse(query).full_path + url = URI.parse(query).request_target else url = "/" end @@ -1978,7 +1978,7 @@ get "/api/v1/captions/:id" do |env| caption = caption[0] end - url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").full_path + url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").request_target # Auto-generated captions often have cues that aren't aligned properly with the video, # as well as some other markup that makes it cumbersome, so we try to fix that here @@ -3184,7 +3184,7 @@ get "/api/manifest/dash/id/:id" do |env| end if dashmpd = video.dash_manifest_url - manifest = YT_POOL.client &.get(URI.parse(dashmpd).full_path).body + manifest = YT_POOL.client &.get(URI.parse(dashmpd).request_target).body manifest = manifest.gsub(/[^<]+<\/BaseURL>/) do |baseurl| url = baseurl.lchop("") @@ -3192,7 +3192,7 @@ get "/api/manifest/dash/id/:id" do |env| if local uri = URI.parse(url) - url = "#{uri.full_path}host/#{uri.host}/" + url = "#{uri.request_target}host/#{uri.host}/" end "#{url}" @@ -3205,7 +3205,7 @@ get "/api/manifest/dash/id/:id" do |env| if local adaptive_fmts.each do |fmt| - fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) + fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) end end @@ -3403,7 +3403,7 @@ get "/latest_version" do |env| next end - url = URI.parse(url).full_path.not_nil! if local + url = URI.parse(url).request_target.not_nil! if local url = "#{url}&title=#{title}" if title env.redirect url @@ -3515,7 +3515,7 @@ get "/videoplayback" do |env| client = make_client(URI.parse(new_host), region) end - url = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" + url = "#{location.request_target}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" else break end @@ -3555,7 +3555,7 @@ get "/videoplayback" do |env| if location = response.headers["Location"]? location = URI.parse(location) - location = "#{location.full_path}&host=#{location.host}" + location = "#{location.request_target}&host=#{location.host}" if region location += "®ion=#{region}" @@ -3619,7 +3619,7 @@ get "/videoplayback" do |env| if location = response.headers["Location"]? location = URI.parse(location) - location = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" + location = "#{location.request_target}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" env.redirect location break @@ -3859,7 +3859,7 @@ end get "/watch_videos" do |env| response = YT_POOL.client &.get(env.request.resource) if url = response.headers["Location"]? - url = URI.parse(url).full_path + url = URI.parse(url).request_target next env.redirect url end @@ -3874,7 +3874,7 @@ error 404 do |env| response = YT_POOL.client &.get("/#{item}") if response.status_code == 301 - response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).full_path) + response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).request_target) end if response.body.empty? diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index 0ac99ba5..a8bbf74b 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -294,7 +294,7 @@ def template_youtube_comments(comments, locale, thin_mode) end if !thin_mode - author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).full_path}" + author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).request_target}" else author_thumbnail = "" end @@ -322,7 +322,7 @@ def template_youtube_comments(comments, locale, thin_mode) html << <<-END_HTML
- +
END_HTML @@ -375,7 +375,7 @@ def template_youtube_comments(comments, locale, thin_mode) if child["creatorHeart"]? if !thin_mode - creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).full_path}" + creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).request_target}" else creator_thumbnail = "" end @@ -473,7 +473,7 @@ def replace_links(html) params = HTTP::Params.parse(url.query.not_nil!) anchor["href"] = params["q"]? else - anchor["href"] = url.full_path + anchor["href"] = url.request_target end elsif url.to_s == "#" begin @@ -544,7 +544,7 @@ def content_to_comment_html(content) if url.path == "/redirect" url = HTTP::Params.parse(url.query.not_nil!)["q"] else - url = url.full_path + url = url.request_target end end diff --git a/src/invidious/helpers/proxy.cr b/src/invidious/helpers/proxy.cr index 7a42ef41..3418d887 100644 --- a/src/invidious/helpers/proxy.cr +++ b/src/invidious/helpers/proxy.cr @@ -71,14 +71,14 @@ end class HTTPClient < HTTP::Client def set_proxy(proxy : HTTPProxy) begin - @socket = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options) + @io = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options) rescue IO::Error - @socket = nil + @io = nil end end def unset_proxy - @socket = nil + @io = nil end def proxy_connection_options diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index 7d94a6e5..2c95a373 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -329,7 +329,7 @@ def get_referer(env, fallback = "/", unroll = true) end end - referer = referer.full_path + referer = referer.request_target referer = "/" + referer.gsub(/[^\/?@&%=\-_.0-9a-zA-Z]/, "").lstrip("/\\") if referer == env.request.path diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr index 8b1aed5f..4269e123 100644 --- a/src/invidious/jobs/bypass_captcha_job.cr +++ b/src/invidious/jobs/bypass_captcha_job.cr @@ -60,7 +60,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob elsif response.headers["Location"]?.try &.includes?("/sorry/index") location = response.headers["Location"].try { |u| URI.parse(u) } headers = HTTP::Headers{":authority" => location.host.not_nil!} - response = YT_POOL.client &.get(location.full_path, headers) + response = YT_POOL.client &.get(location.request_target, headers) html = XML.parse_html(response.body) form = html.xpath_node(%(//form[@action="index"])).not_nil! diff --git a/src/invidious/routes/embed.cr b/src/invidious/routes/embed.cr index 4fd265c9..5db32788 100644 --- a/src/invidious/routes/embed.cr +++ b/src/invidious/routes/embed.cr @@ -144,8 +144,8 @@ class Invidious::Routes::Embed < Invidious::Routes::BaseRoute adaptive_fmts = video.adaptive_fmts if params.local - fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } - adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } + fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } + adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } end video_streams = video.video_streams diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr index 662fdf13..ffe5f568 100644 --- a/src/invidious/routes/login.cr +++ b/src/invidious/routes/login.cr @@ -255,7 +255,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute traceback << "Unhandled dialog /b/0/SmsAuthInterstitial." end - login = client.get(location.full_path, headers) + login = client.get(location.request_target, headers) headers = login.cookies.add_request_headers(headers) location = login.headers["Location"]?.try { |u| URI.parse(u) } diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr index 65604a88..8169e1ed 100644 --- a/src/invidious/routes/watch.cr +++ b/src/invidious/routes/watch.cr @@ -126,8 +126,8 @@ class Invidious::Routes::Watch < Invidious::Routes::BaseRoute adaptive_fmts = video.adaptive_fmts if params.local - fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } - adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) } + fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } + adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) } end video_streams = video.video_streams diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr index caa0ad0e..061d7eec 100644 --- a/src/invidious/views/channel.ecr +++ b/src/invidious/views/channel.ecr @@ -5,7 +5,7 @@ <% if channel.banner %>
- "> + ">
@@ -16,7 +16,7 @@
- + <%= channel.author %>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr index 69724390..3c4eaabb 100644 --- a/src/invidious/views/community.ecr +++ b/src/invidious/views/community.ecr @@ -4,7 +4,7 @@ <% if channel.banner %>
- "> + ">
@@ -15,7 +15,7 @@
- + <%= channel.author %>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index e4a60697..1380d754 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -5,7 +5,7 @@ <% if !env.get("preferences").as(Preferences).thin_mode %>
- +
<% end %>

<%= item.author %>

@@ -15,7 +15,7 @@
<%= item.description_html %>
<% when SearchPlaylist, InvidiousPlaylist %> <% if item.id.starts_with? "RD" %> - <% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").full_path.split("/")[2]}" %> + <% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").request_target.split("/")[2]}" %> <% else %> <% url = "/playlist?list=#{item.id}" %> <% end %> @@ -23,7 +23,7 @@
<% if !env.get("preferences").as(Preferences).thin_mode %>
- "/> + "/>

<%= number_with_separator(item.video_count) %> videos

<% end %> diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr index 625c6fee..a898a41f 100644 --- a/src/invidious/views/components/player.ecr +++ b/src/invidious/views/components/player.ecr @@ -4,7 +4,7 @@ <% if params.video_loop %>loop<% end %> <% if params.controls %>controls<% end %>> <% if (hlsvp = video.hls_manifest_url) && !CONFIG.disabled?("livestreams") %> - + <% else %> <% if params.listen %> <% audio_streams.each_with_index do |fmt, i| %> diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr index a77d106d..44bdb94d 100644 --- a/src/invidious/views/playlists.ecr +++ b/src/invidious/views/playlists.ecr @@ -4,7 +4,7 @@ <% if channel.banner %>
- "> + ">
@@ -15,7 +15,7 @@
- + <%= channel.author %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 786a88b6..7cbe5e3f 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -203,7 +203,7 @@
<% if !video.author_thumbnail.empty? %> - + <% end %> <%= video.author %>
From 5311683d43b9d604c8ea62e19394bd10781ac5b3 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sun, 31 Jan 2021 20:28:21 +0100 Subject: [PATCH 06/35] Update to Crystal 0.36.0 Crystal versions below `0.36.0` are no longer supported. --- .github/workflows/ci.yml | 2 +- docker/Dockerfile | 2 +- shard.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc0e8096..dbf103dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Install Crystal uses: oprypin/install-crystal@v1.2.4 with: - crystal: 0.35.1 + crystal: 0.36.0 - name: Cache Shards uses: actions/cache@v2 diff --git a/docker/Dockerfile b/docker/Dockerfile index ce4cc765..65b2b68e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM crystallang/crystal:0.35.1-alpine AS builder +FROM crystallang/crystal:0.36.0-alpine AS builder RUN apk add --no-cache curl sqlite-static WORKDIR /invidious COPY ./shard.yml ./shard.yml diff --git a/shard.yml b/shard.yml index e0fa1d25..1f89b468 100644 --- a/shard.yml +++ b/shard.yml @@ -29,6 +29,6 @@ dependencies: github: iv-org/lsquic.cr version: ~> 2.18.1-1 -crystal: 0.35.1 +crystal: 0.36.0 license: AGPLv3 From 5c8ab35f5572338483fd982c180cdb1803639215 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Thu, 4 Feb 2021 05:11:54 +0100 Subject: [PATCH 07/35] Bump dependencies --- shard.lock | 4 ++-- shard.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/shard.lock b/shard.lock index 5dbac470..a9074b32 100644 --- a/shard.lock +++ b/shard.lock @@ -22,7 +22,7 @@ shards: pg: git: https://github.com/will/crystal-pg.git - version: 0.22.1 + version: 0.23.1 pool: git: https://github.com/ysbaddaden/pool.git @@ -38,5 +38,5 @@ shards: sqlite3: git: https://github.com/crystal-lang/crystal-sqlite3.git - version: 0.17.0 + version: 0.18.0 diff --git a/shard.yml b/shard.yml index 1f89b468..3cc964f2 100644 --- a/shard.yml +++ b/shard.yml @@ -12,10 +12,10 @@ targets: dependencies: pg: github: will/crystal-pg - version: ~> 0.22.1 + version: ~> 0.23.1 sqlite3: github: crystal-lang/crystal-sqlite3 - version: ~> 0.17.0 + version: ~> 0.18.0 kemal: github: kemalcr/kemal version: ~> 0.27.0 From 689795e8bc1b9bcc074d1eed568a755d4a635111 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Thu, 4 Feb 2021 05:13:29 +0100 Subject: [PATCH 08/35] Update to Crystal 0.36.1 --- .github/workflows/ci.yml | 2 +- docker/Dockerfile | 2 +- shard.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbf103dd..66aacff9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Install Crystal uses: oprypin/install-crystal@v1.2.4 with: - crystal: 0.36.0 + crystal: 0.36.1 - name: Cache Shards uses: actions/cache@v2 diff --git a/docker/Dockerfile b/docker/Dockerfile index 65b2b68e..b88a76c0 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM crystallang/crystal:0.36.0-alpine AS builder +FROM crystallang/crystal:0.36.1-alpine AS builder RUN apk add --no-cache curl sqlite-static WORKDIR /invidious COPY ./shard.yml ./shard.yml diff --git a/shard.yml b/shard.yml index 3cc964f2..42eda04c 100644 --- a/shard.yml +++ b/shard.yml @@ -29,6 +29,6 @@ dependencies: github: iv-org/lsquic.cr version: ~> 2.18.1-1 -crystal: 0.36.0 +crystal: 0.36.1 license: AGPLv3 From 148f3002ec5a1c3e9aba9c03555cad7315a03159 Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Wed, 27 Jan 2021 12:55:29 -0500 Subject: [PATCH 09/35] use large thumbnail for channels in search --- 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 1380d754..ea7d356c 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -5,7 +5,7 @@
<% if !env.get("preferences").as(Preferences).thin_mode %>
- + "/>
<% end %>

<%= item.author %>

From 2b1463304702e2488e249df9a01d67fa234a42b6 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Mon, 8 Feb 2021 16:23:57 +0100 Subject: [PATCH 10/35] Split enhancement and feature request, apply suggestions --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- .github/ISSUE_TEMPLATE/enhancement.md | 24 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 3 ++- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/enhancement.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8b83cbe5..c0485266 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Create a report to help us improve Invidious +about: Create a bug report to help us improve Invidious title: '[Bug] ' labels: bug assignees: '' @@ -9,7 +9,7 @@ assignees: '' - + **Describe the bug** diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md new file mode 100644 index 00000000..7823e1df --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -0,0 +1,24 @@ +--- +name: Enhancement +about: Suggest an enhancement for an existing feature +title: '[Enhancement] ' +labels: enhancement +assignees: '' + +--- + + + + + +**Is your enhancement request related to a problem? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index b308eb0d..59692a51 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,12 +2,13 @@ name: Feature request about: Suggest an idea for this project title: '[Feature request] ' -labels: enhancement +labels: feature-request assignees: '' --- + **Is your feature request related to a problem? Please describe.** From 2bf445e1655cacec40b927b87b32cd0adff6232e Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Wed, 10 Feb 2021 01:04:27 +0100 Subject: [PATCH 11/35] Fix playlists with `Various Artists` author --- src/invidious/helpers/helpers.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index 00087143..944d869b 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -231,7 +231,7 @@ def extract_item(item : JSON::Any, author_fallback : String? = nil, author_id_fa video_id = i["videoId"].as_s title = i["title"].try { |t| t["simpleText"]?.try &.as_s || t["runs"]?.try &.as_a.map(&.["text"].as_s).join("") } || "" - author_info = i["ownerText"]?.try &.["runs"].as_a[0]? + author_info = i["ownerText"]?.try &.["runs"]?.try &.as_a?.try &.[0]? author = author_info.try &.["text"].as_s || author_fallback || "" author_id = author_info.try &.["navigationEndpoint"]?.try &.["browseEndpoint"]["browseId"].as_s || author_id_fallback || "" @@ -322,7 +322,7 @@ def extract_item(item : JSON::Any, author_fallback : String? = nil, author_id_fa video_count = i["videoCount"]?.try &.as_s.to_i || 0 playlist_thumbnail = i["thumbnails"].as_a[0]?.try &.["thumbnails"]?.try &.as_a[0]?.try &.["url"].as_s || "" - author_info = i["shortBylineText"]?.try &.["runs"].as_a[0]? + author_info = i["shortBylineText"]?.try &.["runs"]?.try &.as_a?.try &.[0]? author = author_info.try &.["text"].as_s || author_fallback || "" author_id = author_info.try &.["navigationEndpoint"]?.try &.["browseEndpoint"]["browseId"].as_s || author_id_fallback || "" From c4b67b4cae947a0a99db62600c27c3102a292fe7 Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Sun, 7 Feb 2021 22:37:46 +0100 Subject: [PATCH 12/35] Add Hebrew translation --- locales/he.json | 414 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 locales/he.json diff --git a/locales/he.json b/locales/he.json new file mode 100644 index 00000000..7ce450aa --- /dev/null +++ b/locales/he.json @@ -0,0 +1,414 @@ +{ + "`x` subscribers": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` videos": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` playlists": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "LIVE": "", + "Shared `x` ago": "", + "Unsubscribe": "", + "Subscribe": "", + "View channel on YouTube": "", + "View playlist on YouTube": "", + "newest": "", + "oldest": "", + "popular": "", + "last": "", + "Next page": "", + "Previous page": "", + "Clear watch history?": "", + "New password": "", + "New passwords must match": "", + "Cannot change password for Google accounts": "", + "Authorize token?": "", + "Authorize token for `x`?": "", + "Yes": "", + "No": "", + "Import and Export Data": "", + "Import": "", + "Import Invidious data": "", + "Import YouTube subscriptions": "", + "Import FreeTube subscriptions (.db)": "", + "Import NewPipe subscriptions (.json)": "", + "Import NewPipe data (.zip)": "", + "Export": "", + "Export subscriptions as OPML": "", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "", + "Export data as JSON": "", + "Delete account?": "", + "History": "", + "An alternative front-end to YouTube": "", + "JavaScript license information": "", + "source": "", + "Log in": "", + "Log in/register": "", + "Log in with Google": "", + "User ID": "", + "Password": "", + "Time (h:mm:ss):": "", + "Text CAPTCHA": "", + "Image CAPTCHA": "", + "Sign In": "", + "Register": "", + "E-mail": "", + "Google verification code": "", + "Preferences": "", + "Player preferences": "", + "Always loop: ": "", + "Autoplay: ": "", + "Play next by default: ": "", + "Autoplay next video: ": "", + "Listen by default: ": "", + "Proxy videos: ": "", + "Default speed: ": "", + "Preferred video quality: ": "", + "Player volume: ": "", + "Default comments: ": "", + "youtube": "", + "reddit": "", + "Default captions: ": "", + "Fallback captions: ": "", + "Show related videos: ": "", + "Show annotations by default: ": "", + "Visual preferences": "", + "Player style: ": "", + "Dark mode: ": "", + "Theme: ": "", + "dark": "", + "light": "", + "Thin mode: ": "", + "Subscription preferences": "", + "Show annotations by default for subscribed channels: ": "", + "Redirect homepage to feed: ": "", + "Number of videos shown in feed: ": "", + "Sort videos by: ": "", + "published": "", + "published - reverse": "", + "alphabetically": "", + "alphabetically - reverse": "", + "channel name": "", + "channel name - reverse": "", + "Only show latest video from channel: ": "", + "Only show latest unwatched video from channel: ": "", + "Only show unwatched: ": "", + "Only show notifications (if there are any): ": "", + "Enable web notifications": "", + "`x` uploaded a video": "", + "`x` is live": "", + "Data preferences": "", + "Clear watch history": "", + "Import/export data": "", + "Change password": "", + "Manage subscriptions": "", + "Manage tokens": "", + "Watch history": "", + "Delete account": "", + "Administrator preferences": "", + "Default homepage: ": "", + "Feed menu: ": "", + "Top enabled: ": "", + "CAPTCHA enabled: ": "", + "Login enabled: ": "", + "Registration enabled: ": "", + "Report statistics: ": "", + "Save preferences": "", + "Subscription manager": "", + "Token manager": "", + "Token": "", + "`x` subscriptions": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` tokens": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Import/export": "", + "unsubscribe": "", + "revoke": "", + "Subscriptions": "", + "`x` unseen notifications": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "search": "", + "Log out": "", + "Released under the AGPLv3 by Omar Roth.": "", + "Source available here.": "", + "View JavaScript license information.": "", + "View privacy policy.": "", + "Trending": "", + "Public": "", + "Unlisted": "", + "Private": "", + "View all playlists": "", + "Updated `x` ago": "", + "Delete playlist `x`?": "", + "Delete playlist": "", + "Create playlist": "", + "Title": "", + "Playlist privacy": "", + "Editing playlist `x`": "", + "Watch on YouTube": "", + "Hide annotations": "", + "Show annotations": "", + "Genre: ": "", + "License: ": "", + "Family friendly? ": "", + "Wilson score: ": "", + "Engagement: ": "", + "Whitelisted regions: ": "", + "Blacklisted regions: ": "", + "Shared `x`": "", + "`x` views": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Premieres in `x`": "", + "Premieres `x`": "", + "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", + "View YouTube comments": "", + "View more comments on Reddit": "", + "View `x` comments": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "View Reddit comments": "", + "Hide replies": "", + "Show replies": "", + "Incorrect password": "", + "Quota exceeded, try again in a few hours": "", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", + "Invalid TFA code": "", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "", + "Wrong answer": "", + "Erroneous CAPTCHA": "", + "CAPTCHA is a required field": "", + "User ID is a required field": "", + "Password is a required field": "", + "Wrong username or password": "", + "Please sign in using 'Log in with Google'": "", + "Password cannot be empty": "", + "Password cannot be longer than 55 characters": "", + "Please log in": "", + "Invidious Private Feed for `x`": "", + "channel:`x`": "", + "Deleted or invalid channel": "", + "This channel does not exist.": "", + "Could not get channel info.": "", + "Could not fetch comments": "", + "View `x` replies": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` ago": "", + "Load more": "", + "`x` points": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Could not create mix.": "", + "Empty playlist": "", + "Not a playlist.": "", + "Playlist does not exist.": "", + "Could not pull trending pages.": "", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", + "No such user": "", + "Token is expired, please try again": "", + "English": "", + "English (auto-generated)": "", + "Afrikaans": "", + "Albanian": "", + "Amharic": "", + "Arabic": "", + "Armenian": "", + "Azerbaijani": "", + "Bangla": "", + "Basque": "", + "Belarusian": "", + "Bosnian": "", + "Bulgarian": "", + "Burmese": "", + "Catalan": "", + "Cebuano": "", + "Chinese (Simplified)": "", + "Chinese (Traditional)": "", + "Corsican": "", + "Croatian": "", + "Czech": "", + "Danish": "", + "Dutch": "", + "Esperanto": "", + "Estonian": "", + "Filipino": "", + "Finnish": "", + "French": "", + "Galician": "", + "Georgian": "", + "German": "", + "Greek": "", + "Gujarati": "", + "Haitian Creole": "", + "Hausa": "", + "Hawaiian": "", + "Hebrew": "", + "Hindi": "", + "Hmong": "", + "Hungarian": "", + "Icelandic": "", + "Igbo": "", + "Indonesian": "", + "Irish": "", + "Italian": "", + "Japanese": "", + "Javanese": "", + "Kannada": "", + "Kazakh": "", + "Khmer": "", + "Korean": "", + "Kurdish": "", + "Kyrgyz": "", + "Lao": "", + "Latin": "", + "Latvian": "", + "Lithuanian": "", + "Luxembourgish": "", + "Macedonian": "", + "Malagasy": "", + "Malay": "", + "Malayalam": "", + "Maltese": "", + "Maori": "", + "Marathi": "", + "Mongolian": "", + "Nepali": "", + "Norwegian Bokmål": "", + "Nyanja": "", + "Pashto": "", + "Persian": "", + "Polish": "", + "Portuguese": "", + "Punjabi": "", + "Romanian": "", + "Russian": "", + "Samoan": "", + "Scottish Gaelic": "", + "Serbian": "", + "Shona": "", + "Sindhi": "", + "Sinhala": "", + "Slovak": "", + "Slovenian": "", + "Somali": "", + "Southern Sotho": "", + "Spanish": "", + "Spanish (Latin America)": "", + "Sundanese": "", + "Swahili": "", + "Swedish": "", + "Tajik": "", + "Tamil": "", + "Telugu": "", + "Thai": "", + "Turkish": "", + "Ukrainian": "", + "Urdu": "", + "Uzbek": "", + "Vietnamese": "", + "Welsh": "", + "Western Frisian": "", + "Xhosa": "", + "Yiddish": "", + "Yoruba": "", + "Zulu": "", + "`x` years": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` months": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` weeks": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` days": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` hours": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` minutes": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "`x` seconds": { + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" + }, + "Fallback comments: ": "", + "Popular": "", + "Top": "", + "About": "", + "Rating: ": "", + "Language: ": "", + "View as playlist": "", + "Default": "", + "Music": "", + "Gaming": "", + "News": "", + "Movies": "", + "Download": "", + "Download as: ": "", + "%A %B %-d, %Y": "", + "(edited)": "", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "", + "Audio mode": "", + "Video mode": "", + "Videos": "", + "Playlists": "", + "Community": "", + "relevance": "", + "rating": "", + "date": "", + "views": "", + "content_type": "", + "duration": "", + "features": "", + "sort": "", + "hour": "", + "today": "", + "week": "", + "month": "", + "year": "", + "video": "", + "channel": "", + "playlist": "", + "movie": "", + "show": "", + "hd": "", + "subtitles": "", + "creative_commons": "", + "3d": "", + "live": "", + "4k": "", + "location": "", + "hdr": "", + "filter": "", + "Current version: ": "" +} From ec475e57837b7fd4328531f1c1e2cd5c4d2231fd Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Tue, 9 Feb 2021 08:33:39 +0000 Subject: [PATCH 13/35] Update Finnish translation --- locales/fi.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/fi.json b/locales/fi.json index 0b2db9a1..6808bfd1 100644 --- a/locales/fi.json +++ b/locales/fi.json @@ -1,10 +1,10 @@ { "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tilaaja", - "`x` subscribers.": "`x` tilaajaa", + "`x` subscribers.": "`x` tilaajaa.", "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` video", - "`x` videos.": "`x` videota", + "`x` videos.": "`x` videota.", "`x` playlists.([^.,0-9]|^)1([^.,0-9]|$)": "`x` soittolista.([^.,0-9]|^)1([^.,0-9]|$)", - "`x` playlists.": "`x` soittolistaa", + "`x` playlists.": "`x` soittolistaa.", "LIVE": "SUORA", "Shared `x` ago": "Jaettu `x` sitten", "Unsubscribe": "Peruuta tilaus", From 5ef2bbe5d643688ecc8fc6d93cb16b1915bbccd9 Mon Sep 17 00:00:00 2001 From: "Omer I.S" <66558205+omeritzics@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:33:23 +0200 Subject: [PATCH 14/35] Add Hebrew translation (#1753) * Add Hebrew translation * Update he.json * Update he.json * Update he.json * Update he.json * Update he.json * Update he.json * Update he.json * Update he.json Co-authored-by: TheFrenchGhosty <47571719+TheFrenchGhosty@users.noreply.github.com> --- locales/he.json | 756 ++++++++++++++++++++++++------------------------ 1 file changed, 378 insertions(+), 378 deletions(-) diff --git a/locales/he.json b/locales/he.json index 7ce450aa..e38c1cce 100644 --- a/locales/he.json +++ b/locales/he.json @@ -1,414 +1,414 @@ { "`x` subscribers": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "רשום/ה `x`", + "": "`x` רשומים" }, "`x` videos": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "סרטון `x`", + "": "`x` סרטונים" }, "`x` playlists": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "פלייליסט `x`", + "": "`x` פלייליסטים" }, - "LIVE": "", - "Shared `x` ago": "", - "Unsubscribe": "", - "Subscribe": "", - "View channel on YouTube": "", - "View playlist on YouTube": "", - "newest": "", - "oldest": "", - "popular": "", - "last": "", - "Next page": "", - "Previous page": "", - "Clear watch history?": "", - "New password": "", - "New passwords must match": "", - "Cannot change password for Google accounts": "", - "Authorize token?": "", - "Authorize token for `x`?": "", - "Yes": "", - "No": "", - "Import and Export Data": "", - "Import": "", - "Import Invidious data": "", - "Import YouTube subscriptions": "", - "Import FreeTube subscriptions (.db)": "", - "Import NewPipe subscriptions (.json)": "", - "Import NewPipe data (.zip)": "", - "Export": "", - "Export subscriptions as OPML": "", - "Export subscriptions as OPML (for NewPipe & FreeTube)": "", - "Export data as JSON": "", - "Delete account?": "", - "History": "", - "An alternative front-end to YouTube": "", - "JavaScript license information": "", - "source": "", - "Log in": "", - "Log in/register": "", - "Log in with Google": "", - "User ID": "", - "Password": "", - "Time (h:mm:ss):": "", - "Text CAPTCHA": "", - "Image CAPTCHA": "", - "Sign In": "", - "Register": "", - "E-mail": "", - "Google verification code": "", - "Preferences": "", - "Player preferences": "", - "Always loop: ": "", - "Autoplay: ": "", - "Play next by default: ": "", - "Autoplay next video: ": "", - "Listen by default: ": "", - "Proxy videos: ": "", - "Default speed: ": "", - "Preferred video quality: ": "", - "Player volume: ": "", - "Default comments: ": "", - "youtube": "", - "reddit": "", - "Default captions: ": "", - "Fallback captions: ": "", - "Show related videos: ": "", - "Show annotations by default: ": "", - "Visual preferences": "", - "Player style: ": "", - "Dark mode: ": "", - "Theme: ": "", - "dark": "", - "light": "", - "Thin mode: ": "", - "Subscription preferences": "", - "Show annotations by default for subscribed channels: ": "", - "Redirect homepage to feed: ": "", - "Number of videos shown in feed: ": "", - "Sort videos by: ": "", - "published": "", - "published - reverse": "", - "alphabetically": "", - "alphabetically - reverse": "", - "channel name": "", - "channel name - reverse": "", - "Only show latest video from channel: ": "", - "Only show latest unwatched video from channel: ": "", - "Only show unwatched: ": "", - "Only show notifications (if there are any): ": "", - "Enable web notifications": "", - "`x` uploaded a video": "", - "`x` is live": "", - "Data preferences": "", - "Clear watch history": "", - "Import/export data": "", - "Change password": "", - "Manage subscriptions": "", - "Manage tokens": "", - "Watch history": "", - "Delete account": "", - "Administrator preferences": "", - "Default homepage: ": "", - "Feed menu: ": "", - "Top enabled: ": "", - "CAPTCHA enabled: ": "", - "Login enabled: ": "", - "Registration enabled: ": "", - "Report statistics: ": "", - "Save preferences": "", - "Subscription manager": "", - "Token manager": "", - "Token": "", + "LIVE": "LIVE", + "Shared `x` ago": "Shared `x` ago", + "Unsubscribe": "ביטול מינוי", + "Subscribe": "הרשמה למינוי", + "View channel on YouTube": "צפייה בערוץ ב־YouTube", + "View playlist on YouTube": "צפייה בפלייליסט ב־YouTube", + "newest": "newest", + "oldest": "oldest", + "popular": "popular", + "last": "last", + "Next page": "העמוד הבא", + "Previous page": "העמוד הקודם", + "Clear watch history?": "לנקות את היסטוריית הצפייה?", + "New password": "סיסמה חדשה", + "New passwords must match": "New passwords must match", + "Cannot change password for Google accounts": "Cannot change password for Google accounts", + "Authorize token?": "Authorize token?", + "Authorize token for `x`?": "Authorize token for `x`?", + "Yes": "כן", + "No": "לא", + "Import and Export Data": "ייבוא וייצוא נתונים", + "Import": "ייבוא", + "Import Invidious data": "ייבוא נתוני Invidious", + "Import YouTube subscriptions": "ייבוא מינויים מ־YouTube", + "Import FreeTube subscriptions (.db)": "ייבוא מינויים מ־FreeTube (.db)", + "Import NewPipe subscriptions (.json)": "ייבוא מינויים מ־NewPipe (.json)", + "Import NewPipe data (.zip)": "ייבוא נתוני NewPipe (.zip)", + "Export": "ייצוא", + "Export subscriptions as OPML": "Export subscriptions as OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "Export subscriptions as OPML (for NewPipe & FreeTube)", + "Export data as JSON": "ייצוא הנתונים בתור קובץ JSON", + "Delete account?": "למחוק את החשבון?", + "History": "היסטוריה", + "An alternative front-end to YouTube": "ממשק משתמש חלופי ל־YouTube", + "JavaScript license information": "JavaScript license information", + "source": "source", + "Log in": "כניסה", + "Log in/register": "כניסה/הרשמה", + "Log in with Google": "כניסה עם Google", + "User ID": "User ID", + "Password": "סיסמה", + "Time (h:mm:ss):": "Time (h:mm:ss):", + "Text CAPTCHA": "Text CAPTCHA", + "Image CAPTCHA": "Image CAPTCHA", + "Sign In": "התחברות", + "Register": "הרשמה", + "E-mail": "דוא״ל", + "Google verification code": "Google verification code", + "Preferences": "העדפות", + "Player preferences": "העדפות הנגן", + "Always loop: ": "Always loop: ", + "Autoplay: ": "ניגון אוטומטי: ", + "Play next by default: ": "Play next by default: ", + "Autoplay next video: ": "Autoplay next video: ", + "Listen by default: ": "Listen by default: ", + "Proxy videos: ": "Proxy videos: ", + "Default speed: ": "Default speed: ", + "Preferred video quality: ": "Preferred video quality: ", + "Player volume: ": "Player volume: ", + "Default comments: ": "Default comments: ", + "youtube": "youtube", + "reddit": "reddit", + "Default captions: ": "Default captions: ", + "Fallback captions: ": "Fallback captions: ", + "Show related videos: ": "Show related videos: ", + "Show annotations by default: ": "Show annotations by default: ", + "Visual preferences": "העדפות חזותיות", + "Player style: ": "סגנון הנגן: ", + "Dark mode: ": "Dark mode: ", + "Theme: ": "ערכת נושא: ", + "dark": "dark", + "light": "light", + "Thin mode: ": "Thin mode: ", + "Subscription preferences": "Subscription preferences", + "Show annotations by default for subscribed channels: ": "Show annotations by default for subscribed channels? ", + "Redirect homepage to feed: ": "Redirect homepage to feed: ", + "Number of videos shown in feed: ": "Number of videos shown in feed: ", + "Sort videos by: ": "Sort videos by: ", + "published": "published", + "published - reverse": "published - reverse", + "alphabetically": "alphabetically", + "alphabetically - reverse": "alphabetically - reverse", + "channel name": "channel name", + "channel name - reverse": "channel name - reverse", + "Only show latest video from channel: ": "Only show latest video from channel: ", + "Only show latest unwatched video from channel: ": "Only show latest unwatched video from channel: ", + "Only show unwatched: ": "Only show unwatched: ", + "Only show notifications (if there are any): ": "Only show notifications (if there are any): ", + "Enable web notifications": "Enable web notifications", + "`x` uploaded a video": "`x` uploaded a video", + "`x` is live": "`x` is live", + "Data preferences": "העדפות נתונים", + "Clear watch history": "Clear watch history", + "Import/export data": "ייבוא/ייצוא נתונים", + "Change password": "שינוי הסיסמה", + "Manage subscriptions": "ניהול מינויים", + "Manage tokens": "Manage tokens", + "Watch history": "היסטוריית צפייה", + "Delete account": "מחיקת החשבון", + "Administrator preferences": "Administrator preferences", + "Default homepage: ": "Default homepage: ", + "Feed menu: ": "Feed menu: ", + "Top enabled: ": "Top enabled: ", + "CAPTCHA enabled: ": "CAPTCHA enabled: ", + "Login enabled: ": "Login enabled: ", + "Registration enabled: ": "Registration enabled: ", + "Report statistics: ": "Report statistics: ", + "Save preferences": "Save preferences", + "Subscription manager": "Subscription manager", + "Token manager": "Token manager", + "Token": "Token", "`x` subscriptions": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "מינוי `x`", + "": "`x` מינויים" }, "`x` tokens": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` token", + "": "`x` tokens" }, - "Import/export": "", - "unsubscribe": "", - "revoke": "", - "Subscriptions": "", + "Import/export": "ייבוא/ייצוא", + "unsubscribe": "ביטול מנוי", + "revoke": "revoke", + "Subscriptions": "מינויים", "`x` unseen notifications": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` unseen notification", + "": "`x` unseen notifications" }, - "search": "", - "Log out": "", - "Released under the AGPLv3 by Omar Roth.": "", - "Source available here.": "", - "View JavaScript license information.": "", - "View privacy policy.": "", - "Trending": "", - "Public": "", - "Unlisted": "", - "Private": "", - "View all playlists": "", - "Updated `x` ago": "", - "Delete playlist `x`?": "", - "Delete playlist": "", - "Create playlist": "", - "Title": "", - "Playlist privacy": "", - "Editing playlist `x`": "", - "Watch on YouTube": "", - "Hide annotations": "", - "Show annotations": "", - "Genre: ": "", - "License: ": "", - "Family friendly? ": "", - "Wilson score: ": "", - "Engagement: ": "", - "Whitelisted regions: ": "", - "Blacklisted regions: ": "", - "Shared `x`": "", + "search": "search", + "Log out": "יציאה", + "Released under the AGPLv3 by Omar Roth.": "Released under the AGPLv3 by Omar Roth.", + "Source available here.": "קוד המקור זמין כאן.", + "View JavaScript license information.": "View JavaScript license information.", + "View privacy policy.": "View privacy policy.", + "Trending": "Trending", + "Public": "ציבורי", + "Unlisted": "לא רשום", + "Private": "פרטי", + "View all playlists": "View all playlists", + "Updated `x` ago": "הועלה לפני `x`", + "Delete playlist `x`?": "למחוק את פלייליסט `x`?", + "Delete playlist": "מחיקת פלייליסט", + "Create playlist": "יצירת פלייליסט", + "Title": "Title", + "Playlist privacy": "Playlist privacy", + "Editing playlist `x`": "Editing playlist `x`", + "Watch on YouTube": "צפייה ב־YouTube", + "Hide annotations": "Hide annotations", + "Show annotations": "Show annotations", + "Genre: ": "Genre: ", + "License: ": "רישיון: ", + "Family friendly? ": "לכל המשפחה? ", + "Wilson score: ": "Wilson score: ", + "Engagement: ": "Engagement: ", + "Whitelisted regions: ": "Whitelisted regions: ", + "Blacklisted regions: ": "Blacklisted regions: ", + "Shared `x`": "Shared `x`", "`x` views": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` view", + "": "`x` views" }, - "Premieres in `x`": "", - "Premieres `x`": "", - "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "", - "View YouTube comments": "", - "View more comments on Reddit": "", + "Premieres in `x`": "Premieres in `x`", + "Premieres `x`": "Premieres `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.": "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.", + "View YouTube comments": "View YouTube comments", + "View more comments on Reddit": "View more comments on Reddit", "View `x` comments": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "View `x` comment", + "": "View `x` comments" }, - "View Reddit comments": "", - "Hide replies": "", - "Show replies": "", - "Incorrect password": "", - "Quota exceeded, try again in a few hours": "", - "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", - "Invalid TFA code": "", - "Login failed. This may be because two-factor authentication is not turned on for your account.": "", - "Wrong answer": "", - "Erroneous CAPTCHA": "", - "CAPTCHA is a required field": "", - "User ID is a required field": "", - "Password is a required field": "", - "Wrong username or password": "", - "Please sign in using 'Log in with Google'": "", - "Password cannot be empty": "", - "Password cannot be longer than 55 characters": "", - "Please log in": "", - "Invidious Private Feed for `x`": "", - "channel:`x`": "", - "Deleted or invalid channel": "", - "This channel does not exist.": "", - "Could not get channel info.": "", - "Could not fetch comments": "", + "View Reddit comments": "View Reddit comments", + "Hide replies": "הסתרת תגובות", + "Show replies": "הצגת תגובות", + "Incorrect password": "Incorrect password", + "Quota exceeded, try again in a few hours": "Quota exceeded, try again in a few hours", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.", + "Invalid TFA code": "Invalid TFA code", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "Login failed. This may be because two-factor authentication is not turned on for your account.", + "Wrong answer": "תשובה שגויה", + "Erroneous CAPTCHA": "Erroneous CAPTCHA", + "CAPTCHA is a required field": "CAPTCHA is a required field", + "User ID is a required field": "User ID is a required field", + "Password is a required field": "Password is a required field", + "Wrong username or password": "Wrong username or password", + "Please sign in using 'Log in with Google'": "Please sign in using 'Log in with Google'", + "Password cannot be empty": "Password cannot be empty", + "Password cannot be longer than 55 characters": "Password cannot be longer than 55 characters", + "Please log in": "נא להתחבר", + "Invidious Private Feed for `x`": "Invidious Private Feed for `x`", + "channel:`x`": "channel:`x`", + "Deleted or invalid channel": "Deleted or invalid channel", + "This channel does not exist.": "This channel does not exist.", + "Could not get channel info.": "Could not get channel info.", + "Could not fetch comments": "Could not fetch comments", "View `x` replies": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "View `x` reply", + "": "הצגת `x` תגובות" }, - "`x` ago": "", - "Load more": "", + "`x` ago": "לפני `x`", + "Load more": "לטעון עוד", "`x` points": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` point", + "": "`x` points" }, - "Could not create mix.": "", - "Empty playlist": "", - "Not a playlist.": "", - "Playlist does not exist.": "", - "Could not pull trending pages.": "", - "Hidden field \"challenge\" is a required field": "", - "Hidden field \"token\" is a required field": "", - "Erroneous challenge": "", - "Erroneous token": "", - "No such user": "", - "Token is expired, please try again": "", - "English": "", - "English (auto-generated)": "", - "Afrikaans": "", - "Albanian": "", - "Amharic": "", - "Arabic": "", - "Armenian": "", - "Azerbaijani": "", - "Bangla": "", - "Basque": "", - "Belarusian": "", - "Bosnian": "", - "Bulgarian": "", - "Burmese": "", - "Catalan": "", - "Cebuano": "", - "Chinese (Simplified)": "", - "Chinese (Traditional)": "", - "Corsican": "", - "Croatian": "", - "Czech": "", - "Danish": "", - "Dutch": "", - "Esperanto": "", - "Estonian": "", - "Filipino": "", - "Finnish": "", - "French": "", - "Galician": "", - "Georgian": "", - "German": "", - "Greek": "", - "Gujarati": "", - "Haitian Creole": "", - "Hausa": "", - "Hawaiian": "", - "Hebrew": "", - "Hindi": "", - "Hmong": "", - "Hungarian": "", - "Icelandic": "", - "Igbo": "", - "Indonesian": "", - "Irish": "", - "Italian": "", - "Japanese": "", - "Javanese": "", - "Kannada": "", - "Kazakh": "", - "Khmer": "", - "Korean": "", - "Kurdish": "", - "Kyrgyz": "", - "Lao": "", - "Latin": "", - "Latvian": "", - "Lithuanian": "", - "Luxembourgish": "", - "Macedonian": "", - "Malagasy": "", - "Malay": "", - "Malayalam": "", - "Maltese": "", - "Maori": "", - "Marathi": "", - "Mongolian": "", - "Nepali": "", - "Norwegian Bokmål": "", - "Nyanja": "", - "Pashto": "", - "Persian": "", - "Polish": "", - "Portuguese": "", - "Punjabi": "", - "Romanian": "", - "Russian": "", - "Samoan": "", - "Scottish Gaelic": "", - "Serbian": "", - "Shona": "", - "Sindhi": "", - "Sinhala": "", - "Slovak": "", - "Slovenian": "", - "Somali": "", - "Southern Sotho": "", - "Spanish": "", - "Spanish (Latin America)": "", - "Sundanese": "", - "Swahili": "", - "Swedish": "", - "Tajik": "", - "Tamil": "", - "Telugu": "", - "Thai": "", - "Turkish": "", - "Ukrainian": "", - "Urdu": "", - "Uzbek": "", - "Vietnamese": "", - "Welsh": "", - "Western Frisian": "", - "Xhosa": "", - "Yiddish": "", - "Yoruba": "", - "Zulu": "", + "Could not create mix.": "Could not create mix.", + "Empty playlist": "Empty playlist", + "Not a playlist.": "Not a playlist.", + "Playlist does not exist.": "Playlist does not exist.", + "Could not pull trending pages.": "Could not pull trending pages.", + "Hidden field \"challenge\" is a required field": "Hidden field \"challenge\" is a required field", + "Hidden field \"token\" is a required field": "Hidden field \"token\" is a required field", + "Erroneous challenge": "Erroneous challenge", + "Erroneous token": "Erroneous token", + "No such user": "אין משתמש כזה", + "Token is expired, please try again": "Token is expired, please try again", + "English": "אנגלית", + "English (auto-generated)": "אנגלית (נוצר באופן אוטומטי)", + "Afrikaans": "Afrikaans", + "Albanian": "אלבנית", + "Amharic": "אמהרית", + "Arabic": "ערבית", + "Armenian": "ארמנית", + "Azerbaijani": "Azerbaijani", + "Bangla": "Bangla", + "Basque": "Basque", + "Belarusian": "Belarusian", + "Bosnian": "Bosnian", + "Bulgarian": "בולגרית", + "Burmese": "Burmese", + "Catalan": "Catalan", + "Cebuano": "Cebuano", + "Chinese (Simplified)": "סינית (מפושטת)", + "Chinese (Traditional)": "סינית (מסורתית)", + "Corsican": "Corsican", + "Croatian": "קרואטית", + "Czech": "צ׳כית", + "Danish": "Danish", + "Dutch": "Dutch", + "Esperanto": "אספרנטו", + "Estonian": "אסטונית", + "Filipino": "Filipino", + "Finnish": "Finnish", + "French": "צרפתית", + "Galician": "Galician", + "Georgian": "גאורגית", + "German": "גרמנית", + "Greek": "יוונית", + "Gujarati": "Gujarati", + "Haitian Creole": "Haitian Creole", + "Hausa": "האוסה", + "Hawaiian": "Hawaiian", + "Hebrew": "עברית", + "Hindi": "הינדית", + "Hmong": "Hmong", + "Hungarian": "הונגרית", + "Icelandic": "איסלנדית", + "Igbo": "Igbo", + "Indonesian": "אינדונזית", + "Irish": "Irish", + "Italian": "איטלקית", + "Japanese": "יפנית", + "Javanese": "Javanese", + "Kannada": "Kannada", + "Kazakh": "Kazakh", + "Khmer": "Khmer", + "Korean": "קוריאנית", + "Kurdish": "כורדית", + "Kyrgyz": "Kyrgyz", + "Lao": "Lao", + "Latin": "לטינית", + "Latvian": "Latvian", + "Lithuanian": "Lithuanian", + "Luxembourgish": "Luxembourgish", + "Macedonian": "Macedonian", + "Malagasy": "Malagasy", + "Malay": "Malay", + "Malayalam": "Malayalam", + "Maltese": "Maltese", + "Maori": "Maori", + "Marathi": "Marathi", + "Mongolian": "מונגולית", + "Nepali": "נפאלית", + "Norwegian Bokmål": "Norwegian Bokmål", + "Nyanja": "Nyanja", + "Pashto": "Pashto", + "Persian": "פרסית", + "Polish": "פולנית", + "Portuguese": "פורטוגלית", + "Punjabi": "Punjabi", + "Romanian": "רומנית", + "Russian": "רוסית", + "Samoan": "Samoan", + "Scottish Gaelic": "Scottish Gaelic", + "Serbian": "Serbian", + "Shona": "Shona", + "Sindhi": "Sindhi", + "Sinhala": "סינהלית", + "Slovak": "Slovak", + "Slovenian": "Slovenian", + "Somali": "סומלית", + "Southern Sotho": "Southern Sotho", + "Spanish": "ספרדית", + "Spanish (Latin America)": "ספרדית (אמריקה הלטינית)", + "Sundanese": "Sundanese", + "Swahili": "Swahili", + "Swedish": "שוודית", + "Tajik": "Tajik", + "Tamil": "Tamil", + "Telugu": "Telugu", + "Thai": "Thai", + "Turkish": "טורקית", + "Ukrainian": "אוקראינית", + "Urdu": "אורדו", + "Uzbek": "אוזבקית", + "Vietnamese": "וייטנאמית", + "Welsh": "Welsh", + "Western Frisian": "Western Frisian", + "Xhosa": "Xhosa", + "Yiddish": "יידיש", + "Yoruba": "Yoruba", + "Zulu": "Zulu", "`x` years": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "שנה `x`", + "": "`x` שנים" }, "`x` months": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "חודש `x`", + "": "`x` חודשים" }, "`x` weeks": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "שבוע `x`", + "": "`x` שבועות" }, "`x` days": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "יום `x`", + "": "`x` ימים" }, "`x` hours": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "שעה `x`", + "": "`x` שעות" }, "`x` minutes": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "דקה `x`", + "": "`x` דקות" }, "`x` seconds": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "שניה `x`", + "": "`x` שניות" }, - "Fallback comments: ": "", - "Popular": "", - "Top": "", - "About": "", - "Rating: ": "", - "Language: ": "", - "View as playlist": "", - "Default": "", - "Music": "", - "Gaming": "", - "News": "", - "Movies": "", - "Download": "", - "Download as: ": "", - "%A %B %-d, %Y": "", - "(edited)": "", - "YouTube comment permalink": "", - "permalink": "", - "`x` marked it with a ❤": "", - "Audio mode": "", - "Video mode": "", - "Videos": "", - "Playlists": "", - "Community": "", - "relevance": "", - "rating": "", - "date": "", - "views": "", - "content_type": "", - "duration": "", - "features": "", - "sort": "", - "hour": "", - "today": "", - "week": "", - "month": "", - "year": "", - "video": "", - "channel": "", - "playlist": "", - "movie": "", - "show": "", - "hd": "", - "subtitles": "", - "creative_commons": "", - "3d": "", - "live": "", - "4k": "", - "location": "", - "hdr": "", - "filter": "", - "Current version: ": "" + "Fallback comments: ": "Fallback comments: ", + "Popular": "Popular", + "Top": "Top", + "About": "על אודות", + "Rating: ": "דירוג: ", + "Language: ": "שפה: ", + "View as playlist": "הצגה כפלייליסט", + "Default": "ברירת מחדל", + "Music": "מוזיקה", + "Gaming": "משחקים", + "News": "חדשות", + "Movies": "סרטים", + "Download": "הורדה", + "Download as: ": "הורדה בתור: ", + "%A %B %-d, %Y": "%A %B %-d, %Y", + "(edited)": "(edited)", + "YouTube comment permalink": "YouTube comment permalink", + "permalink": "permalink", + "`x` marked it with a ❤": "`x` marked it with a ❤", + "Audio mode": "Audio mode", + "Video mode": "Video mode", + "Videos": "סרטונים", + "Playlists": "פלייליסטים", + "Community": "קהילה", + "relevance": "רלוונטיות", + "rating": "דירוג", + "date": "תאריך העלאה", + "views": "מספר צפיות", + "content_type": "סוג", + "duration": "משך זמן", + "features": "תכונות", + "sort": "מיון לפי", + "hour": "השעה האחרונה", + "today": "היום", + "week": "השבוע", + "month": "החודש", + "year": "השנה", + "video": "סרטון", + "channel": "ערוץ", + "playlist": "פלייליסט", + "movie": "סרט", + "show": "תכנית טלוויזיה", + "hd": "HD", + "subtitles": "כתוביות", + "creative_commons": "Creative Commons", + "3d": "3D", + "live": "Live", + "4k": "4K", + "location": "מיקום", + "hdr": "HDR", + "filter": "סינון", + "Current version: ": "הגרסה הנוכחית: " } From b7c000e4357091044fcae82b4d171371224740ef Mon Sep 17 00:00:00 2001 From: "Omer I.S" Date: Wed, 10 Feb 2021 02:00:47 +0000 Subject: [PATCH 15/35] Update Hebrew translation --- locales/he.json | 402 ++++++++++++++++++++++++------------------------ 1 file changed, 201 insertions(+), 201 deletions(-) diff --git a/locales/he.json b/locales/he.json index e38c1cce..04748857 100644 --- a/locales/he.json +++ b/locales/he.json @@ -1,230 +1,230 @@ { "`x` subscribers": { - "([^.,0-9]|^)1([^.,0-9]|$)": "רשום/ה `x`", - "": "`x` רשומים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` רשומים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` רשומים." }, "`x` videos": { - "([^.,0-9]|^)1([^.,0-9]|$)": "סרטון `x`", - "": "`x` סרטונים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` סרטונים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` סרטונים." }, "`x` playlists": { - "([^.,0-9]|^)1([^.,0-9]|$)": "פלייליסט `x`", - "": "`x` פלייליסטים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` פלייליסטים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` פלייליסטים." }, - "LIVE": "LIVE", - "Shared `x` ago": "Shared `x` ago", + "LIVE": "שידור חי", + "Shared `x` ago": "", "Unsubscribe": "ביטול מינוי", "Subscribe": "הרשמה למינוי", "View channel on YouTube": "צפייה בערוץ ב־YouTube", "View playlist on YouTube": "צפייה בפלייליסט ב־YouTube", - "newest": "newest", - "oldest": "oldest", - "popular": "popular", - "last": "last", + "newest": "", + "oldest": "", + "popular": "", + "last": "", "Next page": "העמוד הבא", "Previous page": "העמוד הקודם", "Clear watch history?": "לנקות את היסטוריית הצפייה?", "New password": "סיסמה חדשה", - "New passwords must match": "New passwords must match", - "Cannot change password for Google accounts": "Cannot change password for Google accounts", - "Authorize token?": "Authorize token?", - "Authorize token for `x`?": "Authorize token for `x`?", + "New passwords must match": "על הסיסמאות החדשות להתאים", + "Cannot change password for Google accounts": "לא ניתן לשנות את הסיסמה לחשבונות Google", + "Authorize token?": "", + "Authorize token for `x`?": "", "Yes": "כן", "No": "לא", "Import and Export Data": "ייבוא וייצוא נתונים", "Import": "ייבוא", "Import Invidious data": "ייבוא נתוני Invidious", "Import YouTube subscriptions": "ייבוא מינויים מ־YouTube", - "Import FreeTube subscriptions (.db)": "ייבוא מינויים מ־FreeTube (.db)", - "Import NewPipe subscriptions (.json)": "ייבוא מינויים מ־NewPipe (.json)", - "Import NewPipe data (.zip)": "ייבוא נתוני NewPipe (.zip)", + "Import FreeTube subscriptions (.db)": "ייבוא מינויים מ־FreeTube‏ (.db)", + "Import NewPipe subscriptions (.json)": "ייבוא מינויים מ־NewPipe‏ (.json)", + "Import NewPipe data (.zip)": "ייבוא נתוני NewPipe‏ (.zip)", "Export": "ייצוא", - "Export subscriptions as OPML": "Export subscriptions as OPML", - "Export subscriptions as OPML (for NewPipe & FreeTube)": "Export subscriptions as OPML (for NewPipe & FreeTube)", + "Export subscriptions as OPML": "ייצוא המינויים בתור OPML", + "Export subscriptions as OPML (for NewPipe & FreeTube)": "ייצוא המינויים בתור OPML (עבור NewPipe ו־FreeTube)", "Export data as JSON": "ייצוא הנתונים בתור קובץ JSON", "Delete account?": "למחוק את החשבון?", "History": "היסטוריה", "An alternative front-end to YouTube": "ממשק משתמש חלופי ל־YouTube", - "JavaScript license information": "JavaScript license information", + "JavaScript license information": "", "source": "source", "Log in": "כניסה", "Log in/register": "כניסה/הרשמה", "Log in with Google": "כניסה עם Google", - "User ID": "User ID", + "User ID": "שם משתמש", "Password": "סיסמה", - "Time (h:mm:ss):": "Time (h:mm:ss):", + "Time (h:mm:ss):": "זמן (h:mm:ss):", "Text CAPTCHA": "Text CAPTCHA", "Image CAPTCHA": "Image CAPTCHA", "Sign In": "התחברות", "Register": "הרשמה", "E-mail": "דוא״ל", - "Google verification code": "Google verification code", + "Google verification code": "קוד האימות של Google", "Preferences": "העדפות", "Player preferences": "העדפות הנגן", - "Always loop: ": "Always loop: ", + "Always loop: ": "", "Autoplay: ": "ניגון אוטומטי: ", - "Play next by default: ": "Play next by default: ", - "Autoplay next video: ": "Autoplay next video: ", - "Listen by default: ": "Listen by default: ", - "Proxy videos: ": "Proxy videos: ", - "Default speed: ": "Default speed: ", - "Preferred video quality: ": "Preferred video quality: ", - "Player volume: ": "Player volume: ", - "Default comments: ": "Default comments: ", - "youtube": "youtube", + "Play next by default: ": "", + "Autoplay next video: ": "", + "Listen by default: ": "", + "Proxy videos: ": "", + "Default speed: ": "מהירות ברירת המחדל: ", + "Preferred video quality: ": "איכות הווידאו המועדפת: ", + "Player volume: ": "", + "Default comments: ": "", + "youtube": "יוטיוב", "reddit": "reddit", - "Default captions: ": "Default captions: ", - "Fallback captions: ": "Fallback captions: ", - "Show related videos: ": "Show related videos: ", - "Show annotations by default: ": "Show annotations by default: ", + "Default captions: ": "", + "Fallback captions: ": "", + "Show related videos: ": "", + "Show annotations by default: ": "", "Visual preferences": "העדפות חזותיות", "Player style: ": "סגנון הנגן: ", - "Dark mode: ": "Dark mode: ", + "Dark mode: ": "מצב כהה: ", "Theme: ": "ערכת נושא: ", - "dark": "dark", - "light": "light", - "Thin mode: ": "Thin mode: ", - "Subscription preferences": "Subscription preferences", + "dark": "כהה", + "light": "בהיר", + "Thin mode: ": "", + "Subscription preferences": "העדפות מינויים", "Show annotations by default for subscribed channels: ": "Show annotations by default for subscribed channels? ", - "Redirect homepage to feed: ": "Redirect homepage to feed: ", - "Number of videos shown in feed: ": "Number of videos shown in feed: ", - "Sort videos by: ": "Sort videos by: ", - "published": "published", - "published - reverse": "published - reverse", - "alphabetically": "alphabetically", - "alphabetically - reverse": "alphabetically - reverse", - "channel name": "channel name", - "channel name - reverse": "channel name - reverse", - "Only show latest video from channel: ": "Only show latest video from channel: ", - "Only show latest unwatched video from channel: ": "Only show latest unwatched video from channel: ", - "Only show unwatched: ": "Only show unwatched: ", - "Only show notifications (if there are any): ": "Only show notifications (if there are any): ", - "Enable web notifications": "Enable web notifications", - "`x` uploaded a video": "`x` uploaded a video", - "`x` is live": "`x` is live", + "Redirect homepage to feed: ": "", + "Number of videos shown in feed: ": "מספר הסרטונים שמוצגים בהזנה: ", + "Sort videos by: ": "מיון הסרטונים לפי: ", + "published": "", + "published - reverse": "", + "alphabetically": "בסדר אלפביתי", + "alphabetically - reverse": "בסדר אלפביתי - הפוך", + "channel name": "שם הערוץ", + "channel name - reverse": "שם הערוץ - הפוך", + "Only show latest video from channel: ": "", + "Only show latest unwatched video from channel: ": "", + "Only show unwatched: ": "", + "Only show notifications (if there are any): ": "", + "Enable web notifications": "", + "`x` uploaded a video": "סרטון הועלה על ידי `x`", + "`x` is live": "`x` בשידור חי", "Data preferences": "העדפות נתונים", - "Clear watch history": "Clear watch history", + "Clear watch history": "ניקוי היסטוריית הצפייה", "Import/export data": "ייבוא/ייצוא נתונים", "Change password": "שינוי הסיסמה", "Manage subscriptions": "ניהול מינויים", - "Manage tokens": "Manage tokens", + "Manage tokens": "", "Watch history": "היסטוריית צפייה", "Delete account": "מחיקת החשבון", - "Administrator preferences": "Administrator preferences", + "Administrator preferences": "", "Default homepage: ": "Default homepage: ", - "Feed menu: ": "Feed menu: ", - "Top enabled: ": "Top enabled: ", - "CAPTCHA enabled: ": "CAPTCHA enabled: ", - "Login enabled: ": "Login enabled: ", - "Registration enabled: ": "Registration enabled: ", - "Report statistics: ": "Report statistics: ", - "Save preferences": "Save preferences", - "Subscription manager": "Subscription manager", + "Feed menu: ": "תפריט ההזנה: ", + "Top enabled: ": "", + "CAPTCHA enabled: ": "", + "Login enabled: ": "", + "Registration enabled: ": "", + "Report statistics: ": "", + "Save preferences": "שמירת ההעדפות", + "Subscription manager": "מנהל המינויים", "Token manager": "Token manager", "Token": "Token", "`x` subscriptions": { - "([^.,0-9]|^)1([^.,0-9]|$)": "מינוי `x`", - "": "`x` מינויים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` מינויים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` מינויים." }, "`x` tokens": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` token", - "": "`x` tokens" + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" }, "Import/export": "ייבוא/ייצוא", "unsubscribe": "ביטול מנוי", - "revoke": "revoke", + "revoke": "", "Subscriptions": "מינויים", "`x` unseen notifications": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` unseen notification", - "": "`x` unseen notifications" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` הודעות שלא נראו.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` הודעות שלא נראו." }, - "search": "search", + "search": "חיפוש", "Log out": "יציאה", - "Released under the AGPLv3 by Omar Roth.": "Released under the AGPLv3 by Omar Roth.", + "Released under the AGPLv3 by Omar Roth.": "מופץ תחת רישיון AGPLv3 על ידי עמר רות׳ (Omar Roth).", "Source available here.": "קוד המקור זמין כאן.", - "View JavaScript license information.": "View JavaScript license information.", - "View privacy policy.": "View privacy policy.", - "Trending": "Trending", + "View JavaScript license information.": "", + "View privacy policy.": "להצגת מדיניות הפרטיות.", + "Trending": "הסרטונים החמים", "Public": "ציבורי", "Unlisted": "לא רשום", "Private": "פרטי", - "View all playlists": "View all playlists", + "View all playlists": "הצגת כל הפלייליסטים", "Updated `x` ago": "הועלה לפני `x`", "Delete playlist `x`?": "למחוק את פלייליסט `x`?", "Delete playlist": "מחיקת פלייליסט", "Create playlist": "יצירת פלייליסט", - "Title": "Title", + "Title": "", "Playlist privacy": "Playlist privacy", - "Editing playlist `x`": "Editing playlist `x`", + "Editing playlist `x`": "", "Watch on YouTube": "צפייה ב־YouTube", - "Hide annotations": "Hide annotations", - "Show annotations": "Show annotations", + "Hide annotations": "", + "Show annotations": "", "Genre: ": "Genre: ", "License: ": "רישיון: ", "Family friendly? ": "לכל המשפחה? ", - "Wilson score: ": "Wilson score: ", - "Engagement: ": "Engagement: ", - "Whitelisted regions: ": "Whitelisted regions: ", - "Blacklisted regions: ": "Blacklisted regions: ", - "Shared `x`": "Shared `x`", + "Wilson score: ": "", + "Engagement: ": "", + "Whitelisted regions: ": "", + "Blacklisted regions: ": "", + "Shared `x`": "", "`x` views": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` view", - "": "`x` views" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` צפיות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` צפיות." }, - "Premieres in `x`": "Premieres in `x`", - "Premieres `x`": "Premieres `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.": "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.", - "View YouTube comments": "View YouTube comments", - "View more comments on Reddit": "View more comments on Reddit", + "Premieres in `x`": "", + "Premieres `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 כבוי. יש ללחוץ כאן להצגת התגובות, נא לקחת בחשבון שהטעינה תיקח קצת יותר זמן.", + "View YouTube comments": "", + "View more comments on Reddit": "", "View `x` comments": { - "([^.,0-9]|^)1([^.,0-9]|$)": "View `x` comment", - "": "View `x` comments" + "([^.,0-9]|^)1([^.,0-9]|$)": "הצגת `x` תגובות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "הצגת `x` תגובות." }, - "View Reddit comments": "View Reddit comments", + "View Reddit comments": "", "Hide replies": "הסתרת תגובות", "Show replies": "הצגת תגובות", - "Incorrect password": "Incorrect password", - "Quota exceeded, try again in a few hours": "Quota exceeded, try again in a few hours", - "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.", - "Invalid TFA code": "Invalid TFA code", - "Login failed. This may be because two-factor authentication is not turned on for your account.": "Login failed. This may be because two-factor authentication is not turned on for your account.", + "Incorrect password": "סיסמה שגויה", + "Quota exceeded, try again in a few hours": "", + "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "", + "Invalid TFA code": "", + "Login failed. This may be because two-factor authentication is not turned on for your account.": "", "Wrong answer": "תשובה שגויה", - "Erroneous CAPTCHA": "Erroneous CAPTCHA", - "CAPTCHA is a required field": "CAPTCHA is a required field", - "User ID is a required field": "User ID is a required field", - "Password is a required field": "Password is a required field", - "Wrong username or password": "Wrong username or password", - "Please sign in using 'Log in with Google'": "Please sign in using 'Log in with Google'", - "Password cannot be empty": "Password cannot be empty", - "Password cannot be longer than 55 characters": "Password cannot be longer than 55 characters", + "Erroneous CAPTCHA": "", + "CAPTCHA is a required field": "", + "User ID is a required field": "חובה למלא את שדה שם המשתמש", + "Password is a required field": "חובה למלא את שדה הסיסמה", + "Wrong username or password": "שם משתמש שגוי או סיסמה שגויה", + "Please sign in using 'Log in with Google'": "", + "Password cannot be empty": "", + "Password cannot be longer than 55 characters": "", "Please log in": "נא להתחבר", - "Invidious Private Feed for `x`": "Invidious Private Feed for `x`", - "channel:`x`": "channel:`x`", - "Deleted or invalid channel": "Deleted or invalid channel", - "This channel does not exist.": "This channel does not exist.", - "Could not get channel info.": "Could not get channel info.", - "Could not fetch comments": "Could not fetch comments", + "Invidious Private Feed for `x`": "", + "channel:`x`": "ערוץ:`x`", + "Deleted or invalid channel": "", + "This channel does not exist.": "הערוץ הזה אינו קיים.", + "Could not get channel info.": "לא היה ניתן לקבל מידע על הערוץ.", + "Could not fetch comments": "לא היה ניתן למשוך את התגובות", "View `x` replies": { - "([^.,0-9]|^)1([^.,0-9]|$)": "View `x` reply", - "": "הצגת `x` תגובות" + "([^.,0-9]|^)1([^.,0-9]|$)": "הצגת `x` תגובות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "הצגת `x` תגובות." }, "`x` ago": "לפני `x`", "Load more": "לטעון עוד", "`x` points": { - "([^.,0-9]|^)1([^.,0-9]|$)": "`x` point", - "": "`x` points" + "([^.,0-9]|^)1([^.,0-9]|$)": "", + "": "" }, - "Could not create mix.": "Could not create mix.", - "Empty playlist": "Empty playlist", - "Not a playlist.": "Not a playlist.", - "Playlist does not exist.": "Playlist does not exist.", - "Could not pull trending pages.": "Could not pull trending pages.", - "Hidden field \"challenge\" is a required field": "Hidden field \"challenge\" is a required field", - "Hidden field \"token\" is a required field": "Hidden field \"token\" is a required field", - "Erroneous challenge": "Erroneous challenge", - "Erroneous token": "Erroneous token", + "Could not create mix.": "", + "Empty playlist": "פלייליסט ריק", + "Not a playlist.": "לא פלייליסט.", + "Playlist does not exist.": "הפלייליסט אינו קיים.", + "Could not pull trending pages.": "", + "Hidden field \"challenge\" is a required field": "", + "Hidden field \"token\" is a required field": "", + "Erroneous challenge": "", + "Erroneous token": "", "No such user": "אין משתמש כזה", - "Token is expired, please try again": "Token is expired, please try again", + "Token is expired, please try again": "", "English": "אנגלית", "English (auto-generated)": "אנגלית (נוצר באופן אוטומטי)", "Afrikaans": "Afrikaans", @@ -233,17 +233,17 @@ "Arabic": "ערבית", "Armenian": "ארמנית", "Azerbaijani": "Azerbaijani", - "Bangla": "Bangla", - "Basque": "Basque", + "Bangla": "בנגלית", + "Basque": "בסקית", "Belarusian": "Belarusian", "Bosnian": "Bosnian", "Bulgarian": "בולגרית", "Burmese": "Burmese", "Catalan": "Catalan", - "Cebuano": "Cebuano", + "Cebuano": "סבואנו", "Chinese (Simplified)": "סינית (מפושטת)", "Chinese (Traditional)": "סינית (מסורתית)", - "Corsican": "Corsican", + "Corsican": "קורסיקאית", "Croatian": "קרואטית", "Czech": "צ׳כית", "Danish": "Danish", @@ -253,114 +253,114 @@ "Filipino": "Filipino", "Finnish": "Finnish", "French": "צרפתית", - "Galician": "Galician", + "Galician": "גליסית", "Georgian": "גאורגית", "German": "גרמנית", "Greek": "יוונית", - "Gujarati": "Gujarati", - "Haitian Creole": "Haitian Creole", + "Gujarati": "גוג׳ראטית", + "Haitian Creole": "קריאולית האיטית", "Hausa": "האוסה", - "Hawaiian": "Hawaiian", + "Hawaiian": "הוואית", "Hebrew": "עברית", "Hindi": "הינדית", - "Hmong": "Hmong", + "Hmong": "", "Hungarian": "הונגרית", "Icelandic": "איסלנדית", - "Igbo": "Igbo", + "Igbo": "", "Indonesian": "אינדונזית", "Irish": "Irish", "Italian": "איטלקית", "Japanese": "יפנית", - "Javanese": "Javanese", - "Kannada": "Kannada", - "Kazakh": "Kazakh", - "Khmer": "Khmer", + "Javanese": "ג'אווה", + "Kannada": "קאנדה", + "Kazakh": "קזחית", + "Khmer": "חמרית", "Korean": "קוריאנית", "Kurdish": "כורדית", - "Kyrgyz": "Kyrgyz", - "Lao": "Lao", + "Kyrgyz": "קירגיזית", + "Lao": "לאית", "Latin": "לטינית", - "Latvian": "Latvian", - "Lithuanian": "Lithuanian", - "Luxembourgish": "Luxembourgish", - "Macedonian": "Macedonian", - "Malagasy": "Malagasy", - "Malay": "Malay", - "Malayalam": "Malayalam", - "Maltese": "Maltese", - "Maori": "Maori", - "Marathi": "Marathi", + "Latvian": "לטבית", + "Lithuanian": "ליטאית", + "Luxembourgish": "לוקסמבורגית", + "Macedonian": "מקדונית", + "Malagasy": "מלגשית", + "Malay": "מלאית", + "Malayalam": "", + "Maltese": "מלטזית", + "Maori": "מאורית", + "Marathi": "מראטהית", "Mongolian": "מונגולית", "Nepali": "נפאלית", "Norwegian Bokmål": "Norwegian Bokmål", - "Nyanja": "Nyanja", - "Pashto": "Pashto", + "Nyanja": "", + "Pashto": "פשטו", "Persian": "פרסית", "Polish": "פולנית", "Portuguese": "פורטוגלית", - "Punjabi": "Punjabi", + "Punjabi": "פנג'אבי", "Romanian": "רומנית", "Russian": "רוסית", - "Samoan": "Samoan", - "Scottish Gaelic": "Scottish Gaelic", + "Samoan": "", + "Scottish Gaelic": "גאלית סקוטית", "Serbian": "Serbian", - "Shona": "Shona", - "Sindhi": "Sindhi", + "Shona": "", + "Sindhi": "סינדהי", "Sinhala": "סינהלית", "Slovak": "Slovak", "Slovenian": "Slovenian", "Somali": "סומלית", - "Southern Sotho": "Southern Sotho", + "Southern Sotho": "", "Spanish": "ספרדית", "Spanish (Latin America)": "ספרדית (אמריקה הלטינית)", - "Sundanese": "Sundanese", - "Swahili": "Swahili", + "Sundanese": "", + "Swahili": "סווהילי", "Swedish": "שוודית", - "Tajik": "Tajik", - "Tamil": "Tamil", - "Telugu": "Telugu", - "Thai": "Thai", + "Tajik": "טג׳יקית", + "Tamil": "טמילית", + "Telugu": "טלוגו", + "Thai": "תאית", "Turkish": "טורקית", "Ukrainian": "אוקראינית", "Urdu": "אורדו", "Uzbek": "אוזבקית", "Vietnamese": "וייטנאמית", - "Welsh": "Welsh", - "Western Frisian": "Western Frisian", - "Xhosa": "Xhosa", + "Welsh": "ולשית", + "Western Frisian": "", + "Xhosa": "קוסה", "Yiddish": "יידיש", - "Yoruba": "Yoruba", - "Zulu": "Zulu", + "Yoruba": "", + "Zulu": "זולו", "`x` years": { - "([^.,0-9]|^)1([^.,0-9]|$)": "שנה `x`", - "": "`x` שנים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` שנים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` שנים." }, "`x` months": { - "([^.,0-9]|^)1([^.,0-9]|$)": "חודש `x`", - "": "`x` חודשים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` חודשים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` חודשים." }, "`x` weeks": { - "([^.,0-9]|^)1([^.,0-9]|$)": "שבוע `x`", - "": "`x` שבועות" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` שבועות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` שבועות." }, "`x` days": { - "([^.,0-9]|^)1([^.,0-9]|$)": "יום `x`", - "": "`x` ימים" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` ימים.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` ימים." }, "`x` hours": { - "([^.,0-9]|^)1([^.,0-9]|$)": "שעה `x`", - "": "`x` שעות" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` שעות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` שעות." }, "`x` minutes": { - "([^.,0-9]|^)1([^.,0-9]|$)": "דקה `x`", - "": "`x` דקות" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` דקות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` דקות." }, "`x` seconds": { - "([^.,0-9]|^)1([^.,0-9]|$)": "שניה `x`", - "": "`x` שניות" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` שניות.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` שניות." }, - "Fallback comments: ": "Fallback comments: ", - "Popular": "Popular", + "Fallback comments: ": "", + "Popular": "", "Top": "Top", "About": "על אודות", "Rating: ": "דירוג: ", @@ -374,10 +374,10 @@ "Download": "הורדה", "Download as: ": "הורדה בתור: ", "%A %B %-d, %Y": "%A %B %-d, %Y", - "(edited)": "(edited)", - "YouTube comment permalink": "YouTube comment permalink", - "permalink": "permalink", - "`x` marked it with a ❤": "`x` marked it with a ❤", + "(edited)": "", + "YouTube comment permalink": "", + "permalink": "", + "`x` marked it with a ❤": "סומנה ב־❤ על ידי `x`", "Audio mode": "Audio mode", "Video mode": "Video mode", "Videos": "סרטונים", From 5025c40ab266bef569b9827ed399e9d1a30bc86f Mon Sep 17 00:00:00 2001 From: John Johnson <0a7aa911-2556-4a8e-8127-cfda3dbd3b5a@ginmal.anonaddy.com> Date: Wed, 10 Feb 2021 13:07:23 +0000 Subject: [PATCH 16/35] Update Hebrew translation --- locales/he.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/locales/he.json b/locales/he.json index 04748857..f5e33877 100644 --- a/locales/he.json +++ b/locales/he.json @@ -17,10 +17,10 @@ "Subscribe": "הרשמה למינוי", "View channel on YouTube": "צפייה בערוץ ב־YouTube", "View playlist on YouTube": "צפייה בפלייליסט ב־YouTube", - "newest": "", - "oldest": "", - "popular": "", - "last": "", + "newest": "החדש ביותר", + "oldest": "הישן ביותר", + "popular": "פופולארי", + "last": "אחרון", "Next page": "העמוד הבא", "Previous page": "העמוד הקודם", "Clear watch history?": "לנקות את היסטוריית הצפייה?", @@ -64,19 +64,19 @@ "Always loop: ": "", "Autoplay: ": "ניגון אוטומטי: ", "Play next by default: ": "", - "Autoplay next video: ": "", - "Listen by default: ": "", + "Autoplay next video: ": "נגן אוטומטית את הסרטון הבא ", + "Listen by default: ": "האזן כברירת מחדל: ", "Proxy videos: ": "", "Default speed: ": "מהירות ברירת המחדל: ", "Preferred video quality: ": "איכות הווידאו המועדפת: ", - "Player volume: ": "", - "Default comments: ": "", + "Player volume: ": "עוצמת שמע בנגן: ", + "Default comments: ": "תגובות ברירת מחדל ", "youtube": "יוטיוב", "reddit": "reddit", - "Default captions: ": "", - "Fallback captions: ": "", - "Show related videos: ": "", - "Show annotations by default: ": "", + "Default captions: ": "כתוביות ברירת מחדל ", + "Fallback captions: ": "כתוביות גיבוי ", + "Show related videos: ": "הראה סרטונים קשורים: ", + "Show annotations by default: ": "הראה הסברים כברירת מחדל: ", "Visual preferences": "העדפות חזותיות", "Player style: ": "סגנון הנגן: ", "Dark mode: ": "מצב כהה: ", @@ -89,16 +89,16 @@ "Redirect homepage to feed: ": "", "Number of videos shown in feed: ": "מספר הסרטונים שמוצגים בהזנה: ", "Sort videos by: ": "מיון הסרטונים לפי: ", - "published": "", + "published": "פורסם", "published - reverse": "", "alphabetically": "בסדר אלפביתי", "alphabetically - reverse": "בסדר אלפביתי - הפוך", "channel name": "שם הערוץ", "channel name - reverse": "שם הערוץ - הפוך", - "Only show latest video from channel: ": "", - "Only show latest unwatched video from channel: ": "", - "Only show unwatched: ": "", - "Only show notifications (if there are any): ": "", + "Only show latest video from channel: ": "הראה רק את הסרטון האחרון מהערוץ: ", + "Only show latest unwatched video from channel: ": "הראה רק את הסרטון האחרון שלא נצפה מהערוץ: ", + "Only show unwatched: ": "הראה רק סרטונים שלא נצפו ", + "Only show notifications (if there are any): ": "הראה רק התראות (אם יש) ", "Enable web notifications": "", "`x` uploaded a video": "סרטון הועלה על ידי `x`", "`x` is live": "`x` בשידור חי", From 34a0bb04f7ee545d19ca965fd4ef42f19f3a882e Mon Sep 17 00:00:00 2001 From: gripped Date: Sun, 14 Feb 2021 10:23:16 +0000 Subject: [PATCH 17/35] Update README.md Ubuntu / Debian instructions installing an old version of Crystal. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e06fa7dc..a3ddfe3b 100644 --- a/README.md +++ b/README.md @@ -91,10 +91,8 @@ $ sudo pacman -S base-devel shards crystal librsvg postgresql # Ubuntu or Debian # First you have to add the repository to your APT configuration. For easy setup just run in your command line: -$ curl -sSL https://dist.crystal-lang.org/apt/setup.sh | sudo bash -# That will add the signing key and the repository configuration. If you prefer to do it manually, execute the following commands: -$ curl -sL "https://keybase.io/crystal/pgp_keys.asc" | sudo apt-key add - -$ echo "deb https://dist.crystal-lang.org/apt crystal main" | sudo tee /etc/apt/sources.list.d/crystal.list +$ curl -fsSL https://crystal-lang.org/install.sh | sudo bash +# That will add the signing key and the repository configuration. If you prefer to do it manually, Follow the instructions here https://crystal-lang.org/install $ sudo apt-get update $ sudo apt install crystal libssl-dev libxml2-dev libyaml-dev libgmp-dev libreadline-dev postgresql librsvg2-bin libsqlite3-dev zlib1g-dev ``` From 6c8d3232a0604a764326da06297c49bbd349e096 Mon Sep 17 00:00:00 2001 From: Riku Viitanen Date: Thu, 11 Feb 2021 18:50:12 +0000 Subject: [PATCH 18/35] Update Finnish translation --- locales/fi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fi.json b/locales/fi.json index 6808bfd1..5dfd4ea2 100644 --- a/locales/fi.json +++ b/locales/fi.json @@ -41,7 +41,7 @@ "An alternative front-end to YouTube": "Vaihtoehtoinen käyttöliittymä YouTubelle", "JavaScript license information": "JavaScript-käyttöoikeustiedot", "source": "lähde", - "Log in": "Kirjaudu sisään", + "Log in": "Kirjaudu", "Log in/register": "Kirjaudu sisään / Rekisteröidy", "Log in with Google": "Kirjaudu sisään Googlella", "User ID": "Käyttäjätunnus", From db36d806699596dc87cf5b2802e81b1a5ad4a1da Mon Sep 17 00:00:00 2001 From: Reza Almanda Date: Sun, 14 Feb 2021 01:05:13 +0000 Subject: [PATCH 19/35] Update Indonesian translation --- locales/id.json | 116 ++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/locales/id.json b/locales/id.json index 62577127..66662c69 100644 --- a/locales/id.json +++ b/locales/id.json @@ -74,7 +74,7 @@ "youtube": "youtube", "reddit": "reddit", "Default captions: ": "Subtitel default: ", - "Fallback captions: ": "", + "Fallback captions: ": "Subtitel fallback: ", "Show related videos: ": "Tampilkan video terkait: ", "Show annotations by default: ": "Tampilkan anotasi secara default: ", "Visual preferences": "Preferensi visual", @@ -163,7 +163,7 @@ "License: ": "Lisensi: ", "Family friendly? ": "Ramah keluarga? ", "Wilson score: ": "Skor Wilson: ", - "Engagement: ": "Keterikatan: ", + "Engagement: ": "Keterlibatan: ", "Whitelisted regions: ": "Wilayah daftar-putih: ", "Blacklisted regions: ": "Wilayah daftar-hitam: ", "Shared `x`": "Berbagi`x`", @@ -211,10 +211,10 @@ "`x` ago": "`x` lalu", "Load more": "Muat lebih banyak", "`x` points": { - "([^.,0-9]|^)1([^.,0-9]|$)": "", - "": "" + "([^.,0-9]|^)1([^.,0-9]|$)": "`x` titik.([^.,0-9]|^)1([^.,0-9]|$)", + "": "`x` titik." }, - "Could not create mix.": "", + "Could not create mix.": "Tidak dapat membuat mix.", "Empty playlist": "Daftar putar kosong", "Not a playlist.": "Bukan daftar putar.", "Playlist does not exist.": "Daftar putar tidak ada.", @@ -232,100 +232,100 @@ "Amharic": "Bahasa Amharik", "Arabic": "Bahasa arab", "Armenian": "Bahasa Armenia", - "Azerbaijani": "", - "Bangla": "", - "Basque": "", - "Belarusian": "", + "Azerbaijani": "Bahasa Azeri", + "Bangla": "Bahasa Bangla", + "Basque": "Bahasa Basque", + "Belarusian": "Bahasa Belarusia", "Bosnian": "Bahasa Bosnia", "Bulgarian": "Bahasa Bulgaria", "Burmese": "Bahasa Birma", - "Catalan": "", - "Cebuano": "", - "Chinese (Simplified)": "", - "Chinese (Traditional)": "", + "Catalan": "Bahasa Catalan", + "Cebuano": "Bahasa Cebu", + "Chinese (Simplified)": "Bahasa Cina", + "Chinese (Traditional)": "Bahasa Cina (Tradisonal)", "Corsican": "", "Croatian": "Bahasa Kroasia", "Czech": "Bahasa Ceko", - "Danish": "", + "Danish": "Bahasa Denmak", "Dutch": "Bahasa Belanda", - "Esperanto": "", - "Estonian": "", - "Filipino": "", - "Finnish": "", - "French": "", + "Esperanto": "Bahasa Esperanto", + "Estonian": "Bahasa Estonia", + "Filipino": "Bahasa Filipina", + "Finnish": "Bahasa Finlandia", + "French": "Bahasa Perancis", "Galician": "", - "Georgian": "", - "German": "", + "Georgian": "Bahasa Georgia", + "German": "Bahasa Jerman", "Greek": "Bahasa Yunani", "Gujarati": "", "Haitian Creole": "", "Hausa": "", - "Hawaiian": "", - "Hebrew": "", - "Hindi": "", + "Hawaiian": "Bahasa Hawai", + "Hebrew": "Bahasa Ibrani", + "Hindi": "Bahasa Hindi", "Hmong": "", - "Hungarian": "", - "Icelandic": "", - "Igbo": "", + "Hungarian": "Bahasa Hungaria", + "Icelandic": "Bahasa Islandia", + "Igbo": "Bahasa Igbo", "Indonesian": "Bahasa Indonesia", - "Irish": "", - "Italian": "", + "Irish": "Bahasa Irlandia", + "Italian": "Bahasa Italia", "Japanese": "Bahasa Jepang", "Javanese": "Bahasa Jawa", "Kannada": "", "Kazakh": "", "Khmer": "", "Korean": "Bahasa Korea", - "Kurdish": "", + "Kurdish": "Bahasa Kurdistan", "Kyrgyz": "", "Lao": "", - "Latin": "", - "Latvian": "", - "Lithuanian": "", + "Latin": "Bahasa Latin", + "Latvian": "Bahasa Latvia", + "Lithuanian": "Bahasa Lithuania", "Luxembourgish": "", "Macedonian": "", "Malagasy": "", "Malay": "Bahasa Melayu", "Malayalam": "", "Maltese": "", - "Maori": "", - "Marathi": "", - "Mongolian": "", - "Nepali": "", + "Maori": "Bahasa Maori", + "Marathi": "Bahasa Marathi", + "Mongolian": "Bahasa Mongolia", + "Nepali": "Bahasa Nepal", "Norwegian Bokmål": "", "Nyanja": "", "Pashto": "", - "Persian": "", - "Polish": "", - "Portuguese": "", - "Punjabi": "", - "Romanian": "", - "Russian": "", + "Persian": "Bahasa Persia", + "Polish": "Bahasa Polandia", + "Portuguese": "Bahasa Portugis", + "Punjabi": "Bahasa Punjabi", + "Romanian": "Bahasa Romania", + "Russian": "Bahasa Russia", "Samoan": "", "Scottish Gaelic": "", - "Serbian": "", + "Serbian": "Bahasa Serbia", "Shona": "", "Sindhi": "", "Sinhala": "", - "Slovak": "", - "Slovenian": "", - "Somali": "", + "Slovak": "Bahasa Slovakia", + "Slovenian": "Bahasa Slovenia", + "Somali": "Bahasa Somalia", "Southern Sotho": "", - "Spanish": "", - "Spanish (Latin America)": "", + "Spanish": "Bahasa Spanyol", + "Spanish (Latin America)": "Bahasa Spanyol (Amerika Latin)", "Sundanese": "Bahasa Sunda", - "Swahili": "", - "Swedish": "", + "Swahili": "Bahasa Swahili", + "Swedish": "Bahasa Swedia", "Tajik": "", - "Tamil": "", + "Tamil": "Bahasa Tamil", "Telugu": "", "Thai": "Bahasa Thailand", - "Turkish": "", - "Ukrainian": "", - "Urdu": "", - "Uzbek": "", + "Turkish": "Bahasa Turki", + "Ukrainian": "Bahasa Ukraina", + "Urdu": "Bahasa Urdu", + "Uzbek": "Bahasa Uzbek", "Vietnamese": "Bahasa Vietnam", - "Welsh": "", + "Welsh": "Bahasa Wales", "Western Frisian": "", "Xhosa": "", "Yiddish": "", @@ -376,7 +376,7 @@ "%A %B %-d, %Y": "", "(edited)": "(disunting)", "YouTube comment permalink": "", - "permalink": "", + "permalink": "permalink", "`x` marked it with a ❤": "`x` telah ditandai dengan ❤", "Audio mode": "Mode audio", "Video mode": "Mode video", From 48bff9a5d2d57f56779c5f0b060fd7367cc3c606 Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty <47571719+TheFrenchGhosty@users.noreply.github.com> Date: Sun, 14 Feb 2021 19:35:05 +0000 Subject: [PATCH 20/35] Enable the Indonesian translation since it's now translated at more than 80% --- src/invidious.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invidious.cr b/src/invidious.cr index ec6df302..ad9333bd 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -85,6 +85,7 @@ LOCALES = { "fi" => load_locale("fi"), "fr" => load_locale("fr"), "hr" => load_locale("hr"), + "id" => load_locale("id"), "is" => load_locale("is"), "it" => load_locale("it"), "ja" => load_locale("ja"), From c451aab1509bccfe4dfef4b2d62d153f985727e7 Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty <47571719+TheFrenchGhosty@users.noreply.github.com> Date: Sun, 14 Feb 2021 19:37:46 +0000 Subject: [PATCH 21/35] Enable the Hebrew translation since it's now translated at more than 80% --- src/invidious.cr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/invidious.cr b/src/invidious.cr index ad9333bd..563a3768 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -84,6 +84,7 @@ LOCALES = { "fa" => load_locale("fa"), "fi" => load_locale("fi"), "fr" => load_locale("fr"), + "he" => load_locale("he"), "hr" => load_locale("hr"), "id" => load_locale("id"), "is" => load_locale("is"), From 3b484c362e607e4f17e0bb68051e7f6bf2140e3a Mon Sep 17 00:00:00 2001 From: 138138138 <78271024+138138138@users.noreply.github.com> Date: Wed, 17 Feb 2021 21:33:26 +0800 Subject: [PATCH 22/35] Skip duration multiply by playback rate Fast Forward/Backward like YouTube. The skip duration is multiplied by playback rate. --- assets/js/player.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/js/player.js b/assets/js/player.js index 04326631..7490bd75 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -430,17 +430,17 @@ window.addEventListener('keydown', e => { case 'ArrowRight': case 'MediaFastForward': - action = skip_seconds.bind(this, 5); + action = skip_seconds.bind(this, 5 * player.playbackRate()); break; case 'ArrowLeft': case 'MediaTrackPrevious': - action = skip_seconds.bind(this, -5); + action = skip_seconds.bind(this, -5 * player.playbackRate()); break; case 'l': - action = skip_seconds.bind(this, 10); + action = skip_seconds.bind(this, 10 * player.playbackRate()); break; case 'j': - action = skip_seconds.bind(this, -10); + action = skip_seconds.bind(this, -10 * player.playbackRate()); break; case '0': From dacb1a70eee85c57e62f9e5c8057cdf372eac1d0 Mon Sep 17 00:00:00 2001 From: saltycrys <73420320+saltycrys@users.noreply.github.com> Date: Sat, 20 Feb 2021 02:58:35 +0100 Subject: [PATCH 23/35] Bump dependencies --- shard.lock | 2 +- shard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shard.lock b/shard.lock index a9074b32..cc1929e8 100644 --- a/shard.lock +++ b/shard.lock @@ -18,7 +18,7 @@ shards: lsquic: git: https://github.com/iv-org/lsquic.cr.git - version: 2.18.1-1 + version: 2.23.1 pg: git: https://github.com/will/crystal-pg.git diff --git a/shard.yml b/shard.yml index 42eda04c..76dcf8b1 100644 --- a/shard.yml +++ b/shard.yml @@ -27,7 +27,7 @@ dependencies: version: ~> 0.1.3 lsquic: github: iv-org/lsquic.cr - version: ~> 2.18.1-1 + version: ~> 2.23.1 crystal: 0.36.1 From 8d53f3abb84d893e25dca7be7e8e319f587c4fe2 Mon Sep 17 00:00:00 2001 From: Perflyst Date: Sat, 20 Feb 2021 19:08:13 +0100 Subject: [PATCH 24/35] Revert "Bump dependencies" --- shard.lock | 2 +- shard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shard.lock b/shard.lock index cc1929e8..a9074b32 100644 --- a/shard.lock +++ b/shard.lock @@ -18,7 +18,7 @@ shards: lsquic: git: https://github.com/iv-org/lsquic.cr.git - version: 2.23.1 + version: 2.18.1-1 pg: git: https://github.com/will/crystal-pg.git diff --git a/shard.yml b/shard.yml index 76dcf8b1..42eda04c 100644 --- a/shard.yml +++ b/shard.yml @@ -27,7 +27,7 @@ dependencies: version: ~> 0.1.3 lsquic: github: iv-org/lsquic.cr - version: ~> 2.23.1 + version: ~> 2.18.1-1 crystal: 0.36.1 From 1e33c0c288f05818beb2c7f483b40c583350e577 Mon Sep 17 00:00:00 2001 From: bopol Date: Sun, 21 Feb 2021 00:08:52 +0100 Subject: [PATCH 25/35] Fix comment replies count --- src/invidious/comments.cr | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index a8bbf74b..13ebbd73 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -195,8 +195,14 @@ def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, so end if node_replies && !response["commentRepliesContinuation"]? - reply_count = (node_replies["moreText"]["simpleText"]? || node_replies["moreText"]["runs"]?.try &.[0]?.try &.["text"]?) - .try &.as_s.gsub(/\D/, "").to_i? || 1 + if node_replies["moreText"]? + reply_count = (node_replies["moreText"]["simpleText"]? || node_replies["moreText"]["runs"]?.try &.[0]?.try &.["text"]?) + .try &.as_s.gsub(/\D/, "").to_i? || 1 + elsif node_replies["viewReplies"]? + reply_count = node_replies["viewReplies"]["buttonRenderer"]["text"]?.try &.["runs"][1]?.try &.["text"]?.try &.as_s.to_i? || 1 + else + reply_count = 1 + end continuation = node_replies["continuations"]?.try &.as_a[0]["nextContinuationData"]["continuation"].as_s continuation ||= "" From 237100da187ed3f19acf12b42d49af1e8bf9f288 Mon Sep 17 00:00:00 2001 From: bopol Date: Sun, 21 Feb 2021 12:35:21 +0100 Subject: [PATCH 26/35] Use UTC for published date --- src/invidious/videos.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 74edc156..b96f4288 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -517,7 +517,7 @@ struct Video end def published : Time - info["microformat"]?.try &.["playerMicroformatRenderer"]?.try &.["publishDate"]?.try { |t| Time.parse(t.as_s, "%Y-%m-%d", Time::Location.local) } || Time.local + info["microformat"]?.try &.["playerMicroformatRenderer"]?.try &.["publishDate"]?.try { |t| Time.parse(t.as_s, "%Y-%m-%d", Time::Location::UTC) } || Time.utc end def published=(other : Time) From 9b79e35d5280e7c7586e44d18930267f7e5237b6 Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Wed, 24 Feb 2021 01:02:55 -0500 Subject: [PATCH 27/35] do not preload captions --- assets/js/player.js | 8 ++++++++ src/invidious/views/components/player.ecr | 7 ++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/assets/js/player.js b/assets/js/player.js index 7490bd75..4db6f98d 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -21,6 +21,7 @@ var options = { ] }, html5: { + preloadTextTracks: false, hls: { overrideNative: true } @@ -547,3 +548,10 @@ window.addEventListener('keydown', e => { if (player.share) { player.share(shareOptions); } + +// show the preferred caption by default +if (player_data.preferred_caption_found) { + player.ready(() => { + player.textTracks()[1].mode = 'showing'; + }); +} \ No newline at end of file diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr index a898a41f..cff3e60a 100644 --- a/src/invidious/views/components/player.ecr +++ b/src/invidious/views/components/player.ecr @@ -24,9 +24,9 @@ <% end %> <% end %> - <% preferred_captions.each_with_index do |caption, i| %> + <% preferred_captions.each do |caption| %> " - label="<%= caption.name.simpleText %>" <% if i == 0 %>default<% end %>> + label="<%= caption.name.simpleText %>"> <% end %> <% captions.each do |caption| %> @@ -42,7 +42,8 @@ "aspect_ratio" => aspect_ratio, "title" => video.title, "description" => HTML.escape(video.short_description), - "thumbnail" => thumbnail + "thumbnail" => thumbnail, + "preferred_caption_found" => !preferred_captions.empty? }.to_pretty_json %> From 903b569f6c115f96bbe96342693eb7681bd2a36f Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Thu, 25 Feb 2021 00:20:19 +0100 Subject: [PATCH 28/35] Massively enhance the README --- README.md | 227 ++++++++---------------------------------------------- 1 file changed, 34 insertions(+), 193 deletions(-) diff --git a/README.md b/README.md index a3ddfe3b..d788b780 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,33 @@ # Invidious -[![Build Status](https://github.com/iv-org/invidious/workflows/Invidious%20CI/badge.svg)](https://github.com/iv-org/invidious/actions) [![Translation Status](https://hosted.weblate.org/widgets/invidious/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/invidious/) +--- ## Invidious is an alternative front-end to YouTube +--- + +[![Build Status](https://github.com/iv-org/invidious/workflows/Invidious%20CI/badge.svg)](https://github.com/iv-org/invidious/actions) [![Translation Status](https://hosted.weblate.org/widgets/invidious/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/invidious/) + +--- + ## Invidious instances: -[Public Invidious instances are listed here.](https://github.com/iv-org/documentation/blob/master/Invidious-Instances.md) +Public Invidious instances are listed on the documentation website: https://docs.invidious.io/Invidious-Instances.md + +--- ## Invidious features: - [Copylefted libre software](https://github.com/iv-org/invidious) (AGPLv3+ licensed) -- Audio-only mode (and no need to keep window open on mobile) - Lightweight (the homepage is ~4 KB compressed) +- Javascript is 100% optional - Tools for managing subscriptions: - Only show unseen videos - Only show latest (or latest unseen) video from each channel - Delivers notifications from all subscribed channels - Automatically redirect homepage to feed - Import subscriptions from YouTube +- Audio-only mode (and no need to keep window open on mobile) - Dark mode - Embed support - Set default player options (speed, quality, autoplay, loop) @@ -26,18 +35,13 @@ - Import/Export subscriptions, watch history, preferences - [Developer API](https://github.com/iv-org/documentation/blob/master/API.md) - Does not use any of the official YouTube APIs -- Does not require JavaScript to play videos - No need to create a Google account to save subscriptions - No ads -- No CoC -- No CLA -- [Multilingual](https://hosted.weblate.org/projects/invidious/#languages) (translated into many languages) +- No Code of Conduct +- No Contributor license Agreement +- Available in many language thanks to [Weblate](https://hosted.weblate.org/projects/)invidious/ -## Donate: - -Bitcoin (BTC): [bc1qfhe7rq3lqzuayzjxzyt9waz9ytrs09kla3tsgr](bitcoin:bc1qfhe7rq3lqzuayzjxzyt9waz9ytrs09kla3tsgr) - -Monero (XMR): [41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3LXqkEJBrCZBgPTwJrDp1FrZJfycGPR](monero:41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3LXqkEJBrCZBgPTwJrDp1FrZJfycGPR) +--- ## Screenshots: @@ -46,198 +50,28 @@ Monero (XMR): [41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3 | [](screenshots/01_player.png?raw=true) | [](screenshots/02_preferences.png?raw=true) | [](screenshots/03_subscriptions.png?raw=true) | | [](screenshots/04_description.png?raw=true) | [](screenshots/05_preferences.png?raw=true) | [](screenshots/06_subscriptions.png?raw=true) | -## Installation: +--- -To manually compile invidious you need at least 2GB of RAM. If you have less you can setup SWAP to have a combined amount of 2 GB or use Docker instead. +## Donate: -After installation take a look at the [Post-install steps](#post-install-configuration). +Bitcoin (BTC): [bc1qfhe7rq3lqzuayzjxzyt9waz9ytrs09kla3tsgr](bitcoin:bc1qfhe7rq3lqzuayzjxzyt9waz9ytrs09kla3tsgr) -### Automated installation: +Monero (XMR): [41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3LXqkEJBrCZBgPTwJrDp1FrZJfycGPR](monero:41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3LXqkEJBrCZBgPTwJrDp1FrZJfycGPR) -[Invidious-Updater](https://github.com/tmiland/Invidious-Updater) is a self-contained script that can automatically install and update Invidious. - -### Docker: - -#### Build and start cluster: - -```bash -$ docker-compose up -``` - -Then visit `localhost:3000` in your browser. - -#### Rebuild cluster: - -```bash -$ docker-compose build -``` - -#### Delete data and rebuild: - -```bash -$ docker volume rm invidious_postgresdata -$ docker-compose build -``` - -### Manual installation: - -### Linux: - -#### Install the dependencies - -```bash -# Arch Linux -$ sudo pacman -S base-devel shards crystal librsvg postgresql - -# Ubuntu or Debian -# First you have to add the repository to your APT configuration. For easy setup just run in your command line: -$ curl -fsSL https://crystal-lang.org/install.sh | sudo bash -# That will add the signing key and the repository configuration. If you prefer to do it manually, Follow the instructions here https://crystal-lang.org/install -$ sudo apt-get update -$ sudo apt install crystal libssl-dev libxml2-dev libyaml-dev libgmp-dev libreadline-dev postgresql librsvg2-bin libsqlite3-dev zlib1g-dev -``` - -#### Add an Invidious user and clone the repository - -```bash -$ useradd -m invidious -$ sudo -i -u invidious -$ git clone https://github.com/iv-org/invidious -$ exit -``` - -#### Set up PostgresSQL - -```bash -$ sudo systemctl enable --now postgresql -$ sudo -i -u postgres -$ psql -c "CREATE USER kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml -$ createdb -O kemal invidious -$ psql invidious kemal < /home/invidious/invidious/config/sql/channels.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/videos.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/channel_videos.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/users.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/session_ids.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/nonces.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/annotations.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/playlists.sql -$ psql invidious kemal < /home/invidious/invidious/config/sql/playlist_videos.sql -$ exit -``` - -#### Set up Invidious - -```bash -$ sudo -i -u invidious -$ cd invidious -$ shards update && shards install -$ crystal build src/invidious.cr --release -# test compiled binary -$ ./invidious # stop with ctrl c -$ exit -``` - -#### Systemd service: - -```bash -$ sudo cp /home/invidious/invidious/invidious.service /etc/systemd/system/invidious.service -$ sudo systemctl enable --now invidious.service -``` - -#### Logrotate: - -```bash -$ echo "/home/invidious/invidious/invidious.log { -rotate 4 -weekly -notifempty -missingok -compress -minsize 1048576 -}" | sudo tee /etc/logrotate.d/invidious.logrotate -$ sudo chmod 0644 /etc/logrotate.d/invidious.logrotate -``` - -### MacOS: - -```bash -# Install dependencies -$ brew update -$ brew install shards crystal postgres imagemagick librsvg - -# Clone the repository and set up a PostgreSQL database -$ git clone https://github.com/iv-org/invidious -$ cd invidious -$ brew services start postgresql -$ psql -c "CREATE ROLE kemal WITH PASSWORD 'kemal';" # Change 'kemal' here to a stronger password, and update `password` in config/config.yml -$ createdb -O kemal invidious -$ psql invidious kemal < config/sql/channels.sql -$ psql invidious kemal < config/sql/videos.sql -$ psql invidious kemal < config/sql/channel_videos.sql -$ psql invidious kemal < config/sql/users.sql -$ psql invidious kemal < config/sql/session_ids.sql -$ psql invidious kemal < config/sql/nonces.sql -$ psql invidious kemal < config/sql/annotations.sql -$ psql invidious kemal < config/sql/privacy.sql -$ psql invidious kemal < config/sql/playlists.sql -$ psql invidious kemal < config/sql/playlist_videos.sql - -# Set up Invidious -$ shards update && shards install -$ crystal build src/invidious.cr --release -``` - -## Post-install configuration: - -Detailed configuration available in the [configuration guide](https://github.com/iv-org/documentation/blob/master/Configuration.md). - -If you use a reverse proxy, you **must** configure invidious to properly serve request through it: - -`https_only: true` : if your are serving your instance via https, set it to true - -`domain: domain.ext`: if you are serving your instance via a domain name, set it here - -`external_port: 443`: if your are serving your instance via https, set it to 443 - -## Update Invidious - -Instructions are available in the [updating guide](https://github.com/iv-org/documentation/blob/master/Updating.md). - -## Usage: - -```bash -$ ./invidious -h -Usage: invidious [arguments] - -b HOST, --bind HOST Host to bind (defaults to 0.0.0.0) - -p PORT, --port PORT Port to listen for connections (defaults to 3000) - -s, --ssl Enables SSL - --ssl-key-file FILE SSL key file - --ssl-cert-file FILE SSL certificate file - -h, --help Shows this help - -c THREADS, --channel-threads=THREADS - Number of threads for refreshing channels (default: 1) - -f THREADS, --feed-threads=THREADS - Number of threads for refreshing feeds (default: 1) - -o OUTPUT, --output=OUTPUT Redirect output (default: STDOUT) - -v, --version Print version -``` - -Or for development: - -```bash -$ curl -fsSLo- https://raw.githubusercontent.com/samueleaton/sentry/master/install.cr | crystal eval -$ ./sentry -🤖 Your SentryBot is vigilant. beep-boop... -``` +--- ## Documentation -The [documentation](https://github.com/iv-org/documentation) can be found in its own repository. +The complete documentation is available on https://docs.invidious.io/ + +--- ## Extensions [Extensions](https://github.com/iv-org/documentation/blob/master/Extensions.md) can be found in the wiki, as well as documentation for integrating it into other projects. +--- + ## Made with Invidious - [FreeTube](https://github.com/FreeTubeApp/FreeTube): A libre software YouTube app for privacy. @@ -247,6 +81,8 @@ The [documentation](https://github.com/iv-org/documentation) can be found in its - [LapisTube](https://github.com/blubbll/lapis-tube): A fancy and advanced (experimental) YouTube front-end. Combined streams & custom YT features. - [HoloPlay](https://github.com/stephane-r/HoloPlay): Funny Android application connecting on Invidious API's with search, playlists and favoris. +--- + ## Contributing 1. Fork it ( https://github.com/iv-org/invidious/fork ) @@ -255,14 +91,19 @@ The [documentation](https://github.com/iv-org/documentation) can be found in its 4. Push to the branch (git push origin my-new-feature) 5. Create a new pull request -#### Translation +### Translation - Log in with an account you have elsewhere, or register an account and start translating at [Hosted Weblate](https://hosted.weblate.org/engage/invidious/). + +--- + ## Contact Feel free to join our [Matrix room](https://matrix.to/#/#invidious:matrix.org), or #invidious on freenode. Both platforms are bridged together. +--- + ## Liability We take no responsibility for the use of our tool, or external instances provided by third parties. We strongly recommend you abide by the valid official regulations in your country. Furthermore, we refuse liability for any inappropriate use of Invidious, such as illegal downloading. This tool is provided to you in the spirit of free, open software. From 01a2383d7b1af5cad7cc373fe80146cc21777911 Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Thu, 25 Feb 2021 00:30:44 +0100 Subject: [PATCH 29/35] Enhance more stuff --- README.md | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index d788b780..5f09faba 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,6 @@ -# Invidious +

Invidious

---- - -## Invidious is an alternative front-end to YouTube - ---- - -[![Build Status](https://github.com/iv-org/invidious/workflows/Invidious%20CI/badge.svg)](https://github.com/iv-org/invidious/actions) [![Translation Status](https://hosted.weblate.org/widgets/invidious/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/invidious/) +

Invidious is an alternative front-end to YouTube.

--- @@ -20,6 +14,8 @@ Public Invidious instances are listed on the documentation website: https://docs - [Copylefted libre software](https://github.com/iv-org/invidious) (AGPLv3+ licensed) - Lightweight (the homepage is ~4 KB compressed) +- No ads +- No tracking - Javascript is 100% optional - Tools for managing subscriptions: - Only show unseen videos @@ -36,10 +32,9 @@ Public Invidious instances are listed on the documentation website: https://docs - [Developer API](https://github.com/iv-org/documentation/blob/master/API.md) - Does not use any of the official YouTube APIs - No need to create a Google account to save subscriptions -- No ads - No Code of Conduct - No Contributor license Agreement -- Available in many language thanks to [Weblate](https://hosted.weblate.org/projects/)invidious/ +- Available in many language, thanks to [Weblate](https://hosted.weblate.org/projects/invidious/) --- @@ -60,19 +55,19 @@ Monero (XMR): [41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3 --- -## Documentation +## Documentation: The complete documentation is available on https://docs.invidious.io/ --- -## Extensions +## Extensions: [Extensions](https://github.com/iv-org/documentation/blob/master/Extensions.md) can be found in the wiki, as well as documentation for integrating it into other projects. --- -## Made with Invidious +## Made with Invidious: - [FreeTube](https://github.com/FreeTubeApp/FreeTube): A libre software YouTube app for privacy. - [CloudTube](https://cadence.moe/cloudtube/subscriptions): A JavaScript-rich alternate YouTube player @@ -83,7 +78,9 @@ The complete documentation is available on https://docs.invidious.io/ --- -## Contributing +## Contributing: + +[![Build Status](https://github.com/iv-org/invidious/workflows/Invidious%20CI/badge.svg)](https://github.com/iv-org/invidious/actions) [![Translation Status](https://hosted.weblate.org/widgets/invidious/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/invidious/) 1. Fork it ( https://github.com/iv-org/invidious/fork ) 2. Create your feature branch (git checkout -b my-new-feature) @@ -91,20 +88,19 @@ The complete documentation is available on https://docs.invidious.io/ 4. Push to the branch (git push origin my-new-feature) 5. Create a new pull request -### Translation +### Translation: - Log in with an account you have elsewhere, or register an account and start translating at [Hosted Weblate](https://hosted.weblate.org/engage/invidious/). - --- -## Contact +## Contact: Feel free to join our [Matrix room](https://matrix.to/#/#invidious:matrix.org), or #invidious on freenode. Both platforms are bridged together. --- -## Liability +## Liability: We take no responsibility for the use of our tool, or external instances provided by third parties. We strongly recommend you abide by the valid official regulations in your country. Furthermore, we refuse liability for any inappropriate use of Invidious, such as illegal downloading. This tool is provided to you in the spirit of free, open software. From 7081e8a226f2302f032e43fe2264b02a3009b783 Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Thu, 25 Feb 2021 00:39:07 +0100 Subject: [PATCH 30/35] Link to docs.invidious.io more --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5f09faba..f33dbd96 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Public Invidious instances are listed on the documentation website: https://docs - Set default player options (speed, quality, autoplay, loop) - Support for Reddit comments in place of YouTube comments - Import/Export subscriptions, watch history, preferences -- [Developer API](https://github.com/iv-org/documentation/blob/master/API.md) +- [Developer API](https://docs.invidious.io/API.md) - Does not use any of the official YouTube APIs - No need to create a Google account to save subscriptions - No Code of Conduct @@ -63,7 +63,7 @@ The complete documentation is available on https://docs.invidious.io/ ## Extensions: -[Extensions](https://github.com/iv-org/documentation/blob/master/Extensions.md) can be found in the wiki, as well as documentation for integrating it into other projects. +[Extensions](https://docs.invidious.io/Extensions.md) can be found in the wiki, as well as documentation for integrating it into other projects. --- From ec28e9fb279944e25d970ec5296216216d2e01ec Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Thu, 25 Feb 2021 00:48:20 +0100 Subject: [PATCH 31/35] Enhance more stuff, again --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f33dbd96..5a4de9b0 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Monero (XMR): [41nMCtek197boJtiUvGnTFYMatrLEpnpkQDmUECqx5Es2uX3sTKKWVhSL76suXsG3 ## Documentation: -The complete documentation is available on https://docs.invidious.io/ +The complete documentation is available on https://docs.invidious.io/ (or alternatively on its own [Github repository](https://github.com/iv-org/documentation)). --- @@ -70,7 +70,7 @@ The complete documentation is available on https://docs.invidious.io/ ## Made with Invidious: - [FreeTube](https://github.com/FreeTubeApp/FreeTube): A libre software YouTube app for privacy. -- [CloudTube](https://cadence.moe/cloudtube/subscriptions): A JavaScript-rich alternate YouTube player +- [CloudTube](https://cadence.moe/cloudtube/subscriptions): A JavaScript-rich alternate YouTube player. - [PeerTubeify](https://gitlab.com/Cha_deL/peertubeify): On YouTube, displays a link to the same video on PeerTube, if it exists. - [MusicPiped](https://github.com/deep-gaurav/MusicPiped): A material design music player that streams music from YouTube. - [LapisTube](https://github.com/blubbll/lapis-tube): A fancy and advanced (experimental) YouTube front-end. Combined streams & custom YT features. @@ -82,11 +82,11 @@ The complete documentation is available on https://docs.invidious.io/ [![Build Status](https://github.com/iv-org/invidious/workflows/Invidious%20CI/badge.svg)](https://github.com/iv-org/invidious/actions) [![Translation Status](https://hosted.weblate.org/widgets/invidious/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/invidious/) -1. Fork it ( https://github.com/iv-org/invidious/fork ) -2. Create your feature branch (git checkout -b my-new-feature) -3. Commit your changes (git commit -am 'Add some feature') -4. Push to the branch (git push origin my-new-feature) -5. Create a new pull request +1. Fork it ( https://github.com/iv-org/invidious/fork ). +2. Create your feature branch (git checkout -b my-new-feature). +3. Commit your changes (git commit -am 'Add some feature'). +4. Push to the branch (git push origin my-new-feature). +5. Create a new pull request. ### Translation: From 08c93e94e43bcf8c07da6e36d08d0dc008c4e2b1 Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty Date: Thu, 25 Feb 2021 00:57:09 +0100 Subject: [PATCH 32/35] Remove Lapis-Tube since it's dead, and update the Cloudtube link --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 5a4de9b0..30d71e04 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,9 @@ The complete documentation is available on https://docs.invidious.io/ (or altern ## Made with Invidious: - [FreeTube](https://github.com/FreeTubeApp/FreeTube): A libre software YouTube app for privacy. -- [CloudTube](https://cadence.moe/cloudtube/subscriptions): A JavaScript-rich alternate YouTube player. +- [CloudTube](https://sr.ht/~cadence/tube/): A JavaScript-rich alternate YouTube player. - [PeerTubeify](https://gitlab.com/Cha_deL/peertubeify): On YouTube, displays a link to the same video on PeerTube, if it exists. - [MusicPiped](https://github.com/deep-gaurav/MusicPiped): A material design music player that streams music from YouTube. -- [LapisTube](https://github.com/blubbll/lapis-tube): A fancy and advanced (experimental) YouTube front-end. Combined streams & custom YT features. - [HoloPlay](https://github.com/stephane-r/HoloPlay): Funny Android application connecting on Invidious API's with search, playlists and favoris. --- From 295e5c9731f3adfd96d900d13e7fce4fd0d5078a Mon Sep 17 00:00:00 2001 From: Andrew Zhao Date: Wed, 24 Feb 2021 23:06:50 -0500 Subject: [PATCH 33/35] show how long ago stream started --- src/invidious/videos.cr | 3 ++- src/invidious/views/watch.ecr | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 74edc156..d0b7d6db 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -534,7 +534,8 @@ struct Video end def live_now - info["videoDetails"]["isLiveContent"]?.try &.as_bool || false + info["microformat"]?.try &.["playerMicroformatRenderer"]? + .try &.["liveBroadcastDetails"]?.try &.["isLiveNow"]?.try &.as_bool || false end def is_listed diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 924914a5..a86e23b2 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -81,6 +81,10 @@

<%= video.premiere_timestamp.try { |t| translate(locale, "Premieres in `x`", recode_date((t - Time.utc).ago, locale)) } %>

+ <% elsif video.live_now %> +

+ <%= video.premiere_timestamp.try { |t| translate(locale, "Started streaming `x` ago", recode_date((Time.utc - t).ago, locale)) } %> +

<% end %>
From 209a986fe43bd6654f55a32c333876dbd5eb700a Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty <47571719+TheFrenchGhosty@users.noreply.github.com> Date: Thu, 25 Feb 2021 12:18:47 +0100 Subject: [PATCH 34/35] Typo Co-authored-by: Perflyst --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30d71e04..f7502636 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Public Invidious instances are listed on the documentation website: https://docs - No need to create a Google account to save subscriptions - No Code of Conduct - No Contributor license Agreement -- Available in many language, thanks to [Weblate](https://hosted.weblate.org/projects/invidious/) +- Available in many languages, thanks to [Weblate](https://hosted.weblate.org/projects/invidious/) --- From 1a78bb4b587e76da1f2c6c5f7313b29174039218 Mon Sep 17 00:00:00 2001 From: TheFrenchGhosty <47571719+TheFrenchGhosty@users.noreply.github.com> Date: Fri, 26 Feb 2021 14:25:20 +0000 Subject: [PATCH 35/35] Use instances.invidious.io --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7502636..ba6c1be5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Invidious instances: -Public Invidious instances are listed on the documentation website: https://docs.invidious.io/Invidious-Instances.md +Public Invidious instances are listed on the documentation website: https://instances.invidious.io/ ---