summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/js/player.js34
-rw-r--r--src/invidious.cr14
-rw-r--r--src/invidious/channels.cr59
-rw-r--r--src/invidious/helpers/jobs.cr4
-rw-r--r--src/invidious/playlists.cr2
5 files changed, 57 insertions, 56 deletions
diff --git a/assets/js/player.js b/assets/js/player.js
index 75370de6..edab35bf 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -231,11 +231,24 @@ function set_time_percent(percent) {
player.currentTime(newTime);
}
+function play() {
+ player.play();
+}
+
+function pause() {
+ player.pause();
+}
+
+function stop() {
+ player.pause();
+ player.currentTime(0);
+}
+
function toggle_play() {
if (player.paused()) {
- player.play();
+ play();
} else {
- player.pause();
+ pause();
}
}
@@ -341,9 +354,22 @@ window.addEventListener('keydown', e => {
switch (decoratedKey) {
case ' ':
case 'k':
+ case 'MediaPlayPause':
action = toggle_play;
break;
+ case 'MediaPlay':
+ action = play;
+ break;
+
+ case 'MediaPause':
+ action = pause;
+ break;
+
+ case 'MediaStop':
+ action = stop;
+ break;
+
case 'ArrowUp':
if (isPlayerFocused) {
action = increase_volume.bind(this, 0.1);
@@ -360,9 +386,11 @@ window.addEventListener('keydown', e => {
break;
case 'ArrowRight':
+ case 'MediaFastForward':
action = skip_seconds.bind(this, 5);
break;
case 'ArrowLeft':
+ case 'MediaTrackPrevious':
action = skip_seconds.bind(this, -5);
break;
case 'l':
@@ -394,9 +422,11 @@ window.addEventListener('keydown', e => {
break;
case 'N':
+ case 'MediaTrackNext':
action = next_video;
break;
case 'P':
+ case 'MediaTrackPrevious':
// TODO: Add support to play back previous video.
break;
diff --git a/src/invidious.cr b/src/invidious.cr
index 2a4c373c..832b4882 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -3412,17 +3412,13 @@ post "/feed/webhook/:token" do |env|
views: video.views,
})
- PG_DB.query_all("UPDATE users SET feed_needs_update = true, notifications = array_append(notifications, $1) \
- WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications)",
- video.id, video.published, video.ucid, as: String)
-
- video_array = video.to_a
- args = arg_array(video_array)
-
- PG_DB.exec("INSERT INTO channel_videos VALUES (#{args}) \
+ was_insert = PG_DB.query_one("INSERT INTO channel_videos VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) \
ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
updated = $4, ucid = $5, author = $6, length_seconds = $7, \
- live_now = $8, premiere_timestamp = $9, views = $10", args: video_array)
+ live_now = $8, premiere_timestamp = $9, views = $10 returning (xmax=0) as was_insert", *video.to_tuple, as: Bool)
+
+ PG_DB.exec("UPDATE users SET notifications = array_append(notifications, $1), \
+ feed_needs_update = true WHERE $2 = ANY(subscriptions)", video.id, video.ucid) if was_insert
end
end
diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr
index 007aa06c..c5600291 100644
--- a/src/invidious/channels.cr
+++ b/src/invidious/channels.cr
@@ -97,6 +97,14 @@ struct ChannelVideo
end
end
end
+
+ def to_tuple
+ {% begin %}
+ {
+ {{*@type.instance_vars.map { |var| var.name }}}
+ }
+ {% end %}
+ end
end
struct AboutRelatedChannel
@@ -260,28 +268,15 @@ def fetch_channel(ucid, db, pull_all_videos = true, locale = nil)
views: views,
})
- emails = db.query_all("UPDATE users SET notifications = array_append(notifications, $1) \
- WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications) RETURNING email",
- video.id, video.published, ucid, as: String)
-
- video_array = video.to_a
- args = arg_array(video_array)
-
# We don't include the 'premiere_timestamp' here because channel pages don't include them,
# meaning the above timestamp is always null
- db.exec("INSERT INTO channel_videos VALUES (#{args}) \
+ was_insert = db.query_one("INSERT INTO channel_videos VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) \
ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
updated = $4, ucid = $5, author = $6, length_seconds = $7, \
- live_now = $8, views = $10", args: video_array)
-
- # Update all users affected by insert
- if emails.empty?
- values = "'{}'"
- else
- values = "VALUES #{emails.map { |email| %((E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}')) }.join(",")}"
- end
+ live_now = $8, views = $10 returning (xmax=0) as was_insert", *video.to_tuple, as: Bool)
- db.exec("UPDATE users SET feed_needs_update = true WHERE email = ANY(#{values})")
+ db.exec("UPDATE users SET notifications = array_append(notifications, $1), \
+ feed_needs_update = true WHERE $2 = ANY(subscriptions)", video.id, video.ucid) if was_insert
end
if pull_all_videos
@@ -315,39 +310,19 @@ def fetch_channel(ucid, db, pull_all_videos = true, locale = nil)
# We are notified of Red videos elsewhere (PubSub), which includes a correct published date,
# so since they don't provide a published date here we can safely ignore them.
if Time.utc - video.published > 1.minute
- emails = db.query_all("UPDATE users SET notifications = array_append(notifications, $1) \
- WHERE updated < $2 AND $3 = ANY(subscriptions) AND $1 <> ALL(notifications) RETURNING email",
- video.id, video.published, video.ucid, as: String)
-
- video_array = video.to_a
- args = arg_array(video_array)
-
- # We don't update the 'premire_timestamp' here because channel pages don't include them
- db.exec("INSERT INTO channel_videos VALUES (#{args}) \
+ was_insert = db.query_one("INSERT INTO channel_videos VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) \
ON CONFLICT (id) DO UPDATE SET title = $2, published = $3, \
updated = $4, ucid = $5, author = $6, length_seconds = $7, \
- live_now = $8, views = $10", args: video_array)
-
- # Update all users affected by insert
- if emails.empty?
- values = "'{}'"
- else
- values = "VALUES #{emails.map { |email| %((E'#{email.gsub({'\'' => "\\'", '\\' => "\\\\"})}')) }.join(",")}"
- end
+ live_now = $8, views = $10 returning (xmax=0) as was_insert", *video.to_tuple, as: Bool)
- db.exec("UPDATE users SET feed_needs_update = true WHERE email = ANY(#{values})")
+ db.exec("UPDATE users SET notifications = array_append(notifications, $1), \
+ feed_needs_update = true WHERE $2 = ANY(subscriptions)", video.id, video.ucid) if was_insert
end
end
- if count < 25
- break
- end
-
+ break if count < 25
page += 1
end
-
- # When a video is deleted from a channel, we find and remove it here
- db.exec("DELETE FROM channel_videos * WHERE NOT id = ANY ('{#{ids.map { |id| %("#{id}") }.join(",")}}') AND ucid = $1", ucid)
end
channel = InvidiousChannel.new({
diff --git a/src/invidious/helpers/jobs.cr b/src/invidious/helpers/jobs.cr
index 4594c1e0..398c2ac8 100644
--- a/src/invidious/helpers/jobs.cr
+++ b/src/invidious/helpers/jobs.cr
@@ -246,7 +246,7 @@ def bypass_captcha(captcha_key, logger)
end
inputs["g-recaptcha-response"] = response["solution"]["gRecaptchaResponse"].as_s
- headers["Cookies"] = response["solution"]["cookies"].as_h.map { |k, v| "#{k}=#{v}" }.join("; ")
+ headers["Cookies"] = response["solution"]["cookies"].as_h?.try &.map { |k, v| "#{k}=#{v}" }.join("; ") || ""
response = YT_POOL.client &.post("/das_captcha", headers, form: inputs)
yield response.cookies.select { |cookie| cookie.name != "PREF" }
@@ -296,7 +296,7 @@ def bypass_captcha(captcha_key, logger)
end
inputs["g-recaptcha-response"] = response["solution"]["gRecaptchaResponse"].as_s
- headers["Cookies"] = response["solution"]["cookies"].as_h.map { |k, v| "#{k}=#{v}" }.join("; ")
+ headers["Cookies"] = response["solution"]["cookies"].as_h?.try &.map { |k, v| "#{k}=#{v}" }.join("; ") || ""
response = YT_POOL.client &.post("/sorry/index", headers: headers, form: inputs)
headers = HTTP::Headers{
"Cookie" => URI.parse(response.headers["location"]).query_params["google_abuse"].split(";")[0],
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index 9190e4e6..c984a12a 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -483,7 +483,7 @@ def extract_playlist_videos(initial_data : Hash(String, JSON::Any))
published: Time.utc,
plid: plid,
live_now: live,
- index: index - 1,
+ index: index,
})
end
end