163 lines
6.0 KiB
JavaScript
163 lines
6.0 KiB
JavaScript
// ==UserScript==
|
|
// @name Improved RedGIFs
|
|
// @namespace BigDuckie.ImprovedRedgifs
|
|
// @version 2025.1.13
|
|
// @description Fix a few annoying "features" and add an easy download button.
|
|
// @icon https://www.google.com/s2/favicons?sz=64&domain=redgifs.com
|
|
// @author Big Duckie
|
|
// @copyright 2025, Big Duckie (https://bigduckie.dev)
|
|
// @license MIT
|
|
// @match https://*.redgifs.com
|
|
// @match https://*.redgifs.com/watch/*
|
|
// @match https://*.redgifs.com/niches/*
|
|
// @match https://*.redgifs.com/ifr/*
|
|
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js
|
|
// @require https://raw.githubusercontent.com/pie6k/jquery.initialize/master/jquery.initialize.min.js
|
|
// @grant GM_addStyle
|
|
// @grant GM_download
|
|
// ==/UserScript==
|
|
|
|
(function () {
|
|
'use strict';
|
|
GM_addStyle(`
|
|
.DLButton {
|
|
background: 0 0;
|
|
border: none;
|
|
cursor: pointer;
|
|
color: var(--white);
|
|
font: var(--s1-medium);
|
|
text-shadow: var(--black) 1px 0 5px;
|
|
text-align: center;
|
|
}
|
|
|
|
.embeddedPlayer .buttons .button svg {
|
|
margin-left: 3px;
|
|
}`);
|
|
|
|
jQuery.noConflict();
|
|
|
|
const play_svg = () => jQuery(document.createElementNS("http://www.w3.org/2000/svg", "svg")).attr({
|
|
width: 24,
|
|
height: 24,
|
|
viewBox: "0 0 24 24",
|
|
fill: "none",
|
|
stroke: "currentColor",
|
|
stroke_width: 2,
|
|
stroke_linecap: "round",
|
|
stroke_linejoin: "round"
|
|
}).html(`<polygon points="5 3 19 12 5 21 5 3"></polygon>`);
|
|
|
|
const pause_svg = () => jQuery(document.createElementNS("http://www.w3.org/2000/svg", "svg")).attr({
|
|
width: 24,
|
|
height: 24,
|
|
viewBox: "0 0 24 24",
|
|
fill: "none",
|
|
stroke: "currentColor",
|
|
stroke_width: 2,
|
|
stroke_linecap: "round",
|
|
stroke_linejoin: "round"
|
|
}).html(`<rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect>`);
|
|
|
|
const download_svg = () => jQuery(document.createElementNS("http://www.w3.org/2000/svg", "svg"))
|
|
.attr({
|
|
width: 24,
|
|
height: 24,
|
|
viewBox: "0 0 24 24",
|
|
fill: "none",
|
|
stroke: "currentColor",
|
|
stroke_width: 2,
|
|
stroke_linecap: "round",
|
|
stroke_linejoin: "round"
|
|
}).html(`<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line>`);
|
|
|
|
// Remove overlayer
|
|
jQuery.initialize(".Player-OverLayer", function() {
|
|
this.remove();
|
|
});
|
|
|
|
// Watch & Niche pages
|
|
jQuery.initialize(".SideBar", function () {
|
|
const gif_root = jQuery(this).parent().parent();
|
|
let gif_id = gif_root.attr("id").substring(4);
|
|
|
|
jQuery(this).find(".SideBar-Item>.rg-button.views").on("click", function () {
|
|
togglePlayer(gif_root.find(".Player-Video>video")[0]);
|
|
}).children("svg").replaceWith(pause_svg());
|
|
|
|
jQuery(this).children(".SideBar-Item:has(.FSButton)").after(
|
|
jQuery("<li>", {
|
|
class: "SideBar-Item"
|
|
}).append(
|
|
jQuery("<button>", {
|
|
class: "DLButton",
|
|
"aria-label": "download video"
|
|
}).append(download_svg()).on("click", () => {
|
|
download(gif_id);
|
|
})
|
|
)
|
|
);
|
|
}, { target: jQuery(".previewFeed")[0] });
|
|
|
|
jQuery.initialize(".Player-Video>video", function () {
|
|
jQuery(this).on("play", function () {
|
|
jQuery(this).parents(".GifPreview").find(".rg-button.views>svg").replaceWith(play_svg());
|
|
}).on("pause", function () {
|
|
jQuery(this).parents(".GifPreview").find(".rg-button.views>svg").replaceWith(pause_svg());
|
|
});
|
|
}, { target: jQuery(".previewFeed")[0] });
|
|
|
|
// IFR pages
|
|
jQuery.initialize(".embeddedPlayer", function () {
|
|
jQuery(this).children(".buttons").prepend(
|
|
jQuery("<div>", {
|
|
class: "button"
|
|
}).append(
|
|
pause_svg().attr({ class: "playButton" })
|
|
).on("click", () => {
|
|
togglePlayer(jQuery(".videoLink>video")[0]);
|
|
})
|
|
)
|
|
|
|
jQuery(this).children(".buttons").append(
|
|
jQuery("<div>", {
|
|
class: "button"
|
|
}).append(
|
|
download_svg()
|
|
).on("click", () => {
|
|
download(window.location.pathname.split("/")[2])
|
|
})
|
|
)
|
|
}, { target: jQuery(".routeWrapper")[0] });
|
|
|
|
jQuery.initialize(".videoLink>video", function () {
|
|
jQuery(this).on("play", function () {
|
|
jQuery(this).parents(".embeddedPlayer").find("svg.playButton").replaceWith(play_svg().attr({ class: "playButton" }));
|
|
}).on("pause", function () {
|
|
jQuery(this).parents(".embeddedPlayer").find("svg.playButton").replaceWith(pause_svg().attr({ class: "playButton" }));
|
|
});
|
|
}, { target: jQuery(".embeddedPlayer")[0] });
|
|
|
|
async function togglePlayer(video) {
|
|
video.paused ? video.play() : video.pause();
|
|
}
|
|
|
|
async function getToken() {
|
|
let token = localStorage.getItem("userscript_access_token") ?? (await (await fetch("https://api.redgifs.com/v2/auth/temporary")).json()).token;
|
|
let tokenData = JSON.parse(atob(token.split(".")[1].replace('-', '+').replace('_', '/')));
|
|
let unixtime = Math.floor(Date.now() / 1000);
|
|
|
|
if (unixtime > tokenData.exp) {
|
|
token = (await (await fetch("https://api.redgifs.com/v2/auth/temporary")).json()).token;
|
|
}
|
|
|
|
localStorage.setItem("userscript_access_token", token);
|
|
return token
|
|
}
|
|
|
|
async function download(id) {
|
|
let token = await getToken()
|
|
let gif = await (await fetch(`https://api.redgifs.com/v2/gifs/${id}`, { headers: { Authorization: `Bearer ${token}` } })).json()
|
|
let url = gif.gif.urls.hd;
|
|
GM_download(url, url.split("/").pop().split("?")[0]);
|
|
}
|
|
})(); |