Skip to content

Instantly share code, notes, and snippets.

@dvingerh
Created October 8, 2024 23:43
Show Gist options
  • Save dvingerh/2b3e853af745aeef6852499287f68b44 to your computer and use it in GitHub Desktop.
Save dvingerh/2b3e853af745aeef6852499287f68b44 to your computer and use it in GitHub Desktop.
discord.restorevideotitle.user.js
// ==UserScript==
// @name Discord Restore Video Player
// @version 1
// @description Discord Restore Video Player
// @namespace Violentmonkey Scripts
// @grant GM_addStyle
// @require http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @require https://raw.githubusercontent.com/pie6k/jquery.initialize/master/jquery.initialize.min.js
// @match *://discord.com/*
// @match *://cdn.discordapp.com/*
// @run-at document-idle
//
// ==/UserScript==
var tooltip = `
<div class="theme-dark images-dark layer_cd0de5 disabledPointerEvents_cd0de5 fileNameTooltip_%GENID%" style="transform: scale(0.98); display:inherit; opacity: 0;height: auto; width: auto;max-width: %MAXWIDTH%px; position: absolute;top: -40px; transition: opacity 0.075s cubic-bezier(0, 0.55, 0.45, 1), transform 0.075s cubic-bezier(0, 0.55, 0.45, 1);">
<div class="tooltip_b6c360 tooltipTop_b6c360 tooltipPrimary_b6c360 tooltipDisablePointerEvents_b6c360 tooltip_e986d9"
style="opacity: 1; transform: none;">
<div class="tooltipPointer_b6c360" style="left: calc(50% + 0px);"></div>
<div class="tooltipContent_b6c360">%FILENAMEFULL%</div>
</div>
</div>
`;
var html = `
<div id="filename" style="
top: 0;
position: absolute;
width: 100%;
height: 5vh;
padding: 10px;
z-index: 1;
background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.35) 45%, rgba(0,0,0,0) 100%);
transition: opacity 0.1s cubic-bezier(0, 0.55, 0.45, 1);
">
<p class="fileNameBanner_%GENID%" id="filename" style="
width: %MAXWIDTH%;
position: relative;
font-family: var(--font-primary);
font-size: 15px;
line-height: 20px;
margin: 0;
font-weight: 500;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
">
%FILENAME%
</p>
<p class="fileNameSize_%GENID%" style="
width: auto;
position: absolute;
font-size: 12px;
font-weight: 500;
line-height: 14px;
color: rgba(255,255,255,0.90);
margin: 4px 0px 0px 0px;
">
%FILESIZE%
</p>
</div>
`;
var fetchHtml = `
<div id="filename" style="
top: 0;
position: absolute;
width: 100%;
height: 5vh;
padding: 10px;
z-index: 1;
background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.35) 45%, rgba(0,0,0,0) 100%);
transition: width 0.05s cubic-bezier(0, 0.55, 0.45, 1), opacity 0.05s cubic-bezier(0, 0.55, 0.45, 1);
"><div class="discord-loader"></div>
<p class="fileNameBannerTemp_%GENID%" id="filename" style="
width: %MAXWIDTH%;
position: relative;
margin: 0;
left: 30px;
font-family: var(--font-primary);
font-size: 15px;
line-height: 20px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
">
<i>Fetching metadata...</i>
</p>
</div>
`;
var loaderCss = `
<style>
.discord-loader {
position: absolute;
border: 4px solid rgba(0, 0, 0, 0.1);
border-left-color: #7289da;
border-radius: 50%;
width: 12px;
height: 12px;
animation: discord-loader 1s infinite;
animation-timing-function: cubic-bezier(0.1, 0.20, 0.6, 0.1);
z-index:3;
}
@keyframes discord-loader {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
`;
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
function genId() {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < 5; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
$(document).ready(function() {
$(loaderCss).appendTo("head");
});
function addTitle(mutation, observer){
if ($(mutation.target).closest("article[class*='embedFull_']").length != 0){
return;
}
if ($(mutation.target).parent().html().indexOf("fileNameBanner_") != -1){
return;
}
let parentWidth = $(mutation.target).width();
let maxWidth = parentWidth;
let redundantWidth = $(mutation.target).closest("div[id*='message-accessories-']").find("div[class*='hoverButtonGroup_']").width() + 10;
if (redundantWidth == 10) {
redundantWidth = 20;
}
let fileUrl = mutation.target.getAttribute('poster');//.replace(/images-ext-\d/g, "media").split("?")[0];
let fileUrlSrc = fileUrl.split("&format=")[0];
let fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1).split("?")[0];
let filenameFull = fileName;
let fileSizeHuman;
let newTooltip = tooltip;
let identifier = genId();
let newHtml = html;
let newFetchHtml = fetchHtml;
newHtml = newHtml.replaceAll("%FILENAMEFULL%", filenameFull).replaceAll("%GENID%", identifier);
newTooltip = newTooltip.replaceAll("%FILENAMEFULL%", filenameFull).replaceAll("%MAXWIDTH%", parentWidth).replaceAll("%GENID%", identifier);
newHtml = newHtml.replaceAll("%MAXWIDTH%", "calc(100% - " + redundantWidth + "px)");
newTooltip = newTooltip.replaceAll("%MAXWIDTH%", maxWidth);
newFetchHtml = newFetchHtml.replaceAll("%MAXWIDTH%", parentWidth).replaceAll("%GENID%", identifier);
$(mutation.target).prepend(newFetchHtml);
fetch(fileUrlSrc, {
method: 'HEAD',
headers: {
'Accept': '*/*',
'Sec-Fetch-Dest': 'video',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'cross-site'
}
})
.then(response => response.headers.get('content-length'))
.then(size => {
fileSizeHuman = formatBytes(size);
newHtml = newHtml.replaceAll("%FILESIZE%", fileSizeHuman);
$(document).find("p[class*='fileNameBannerTemp_" + identifier + "']").parent().remove();
$(newHtml.replaceAll("%FILENAME%", fileName)).insertAfter($(mutation.target));
$(newTooltip).insertAfter($(mutation.target).closest("div[class*='embedWrapper_']").parent());
let fileNameBanner = $(document).find("p[class*='fileNameBanner_" + identifier + "']");
let fileTooltip = $(document).find("div[class*='fileNameTooltip_" + identifier + "']");
let lineHeight = parseInt($(fileTooltip).css('line-height')); // get the line-height of the div in pixels
let height = $(fileTooltip).height(); // get the height of the div in pixels
let numLines = (height / lineHeight) - 1; // calculate the number of lines
if (numLines > 1) {
let curTop = parseInt($(fileTooltip).css("top"));
let newTop = (curTop - (lineHeight * (numLines - 1)));
$(fileTooltip).css({
top: newTop
});
}
var isSeeking = false;
$(mutation.target).on("play", function() {
$(fileNameBanner).parent().css({ opacity: 0, pointerEvents: 'none' });
})
.on("loadedmetadata", function() {
if (mutation.target.autoplay) {
$(fileNameBanner).parent().css({ opacity: 0, pointerEvents: 'none' });
}
})
.on("seeking", function() {
isSeeking = true;
})
.on("seeked", function() {
isSeeking = false;
})
.on("pause", function(e) {
if(!isSeeking) {
$(fileNameBanner).parent().css({ opacity: 1, pointerEvents: 'auto' });
} else {
e.preventDefault(); // Prevent the pause event from being triggered
}
})
.on("ended", function() {
$(fileNameBanner).parent().css({ opacity: 1, pointerEvents: 'auto' });
});
$(fileNameBanner).on("mouseenter", function() {
console.log("in");
$(fileTooltip).css({ opacity: 1, transform: 'scale(1)' });
}).on("mouseleave", function() {
console.log("out");
$(fileTooltip).css({ opacity: 0, transform: 'scale(0.98)' });
});
})
.catch(error => {
console.error('Error:', error);
});
observer.disconnect();
};
$("div[class*='hoverButtonGroup_']").initialize(function() {$(this).css("background-color", "rgba(0,0,0,0.75")});
function handleAttributeFilled(observer, mutations) {
mutations.forEach(function(mutation) {
// Check if the target attribute is now filled
addTitle(mutation, observer);
});
}
$("video[class*='video_']").initialize(function() {
// Initialize MutationObserver to watch for changes in the target
const targetElement = this;
const observer = new MutationObserver(function(mutations) {
handleAttributeFilled(observer, mutations);
});
// Configure and start observing changes in the target element
const observerConfig = { attributes: true , subtree: true,
attributeOldValue: true, childlist: true
};
observer.observe(targetElement, observerConfig);
if ($(this).attr("poster") != "")
{
if ($(this).closest("article[class*='embedFull_']").length != 0){
return;
}
if ($(this).parent().html().indexOf("fileNameBanner_") != -1){
return;
}
let parentWidth = $(this).width();
let maxWidth = parentWidth;
let redundantWidth = $(this).closest("div[id*='message-accessories-']").find("div[class*='hoverButtonGroup_']").width() + 10;
if (redundantWidth == 10) {
redundantWidth = 20;
}
let fileUrl = this.getAttribute('poster');//.replace(/images-ext-\d/g, "media").split("?")[0];
let fileUrlSrc = fileUrl.split("&format=")[0];
let fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1).split("?")[0];
let filenameFull = fileName;
let fileSizeHuman;
let newTooltip = tooltip;
let identifier = genId();
let newHtml = html;
let newFetchHtml = fetchHtml;
newHtml = newHtml.replaceAll("%FILENAMEFULL%", filenameFull).replaceAll("%GENID%", identifier);
newTooltip = newTooltip.replaceAll("%FILENAMEFULL%", filenameFull).replaceAll("%MAXWIDTH%", parentWidth).replaceAll("%GENID%", identifier);
newHtml = newHtml.replaceAll("%MAXWIDTH%", "calc(100% - " + redundantWidth + "px)");
newTooltip = newTooltip.replaceAll("%MAXWIDTH%", maxWidth);
newFetchHtml = newFetchHtml.replaceAll("%MAXWIDTH%", parentWidth).replaceAll("%GENID%", identifier);
$(this).prepend(newFetchHtml);
fetch(fileUrlSrc, {
method: 'HEAD',
headers: {
'Accept': '*/*',
'Sec-Fetch-Dest': 'video',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'cross-site'
}
})
.then(response => response.headers.get('content-length'))
.then(size => {
fileSizeHuman = formatBytes(size);
newHtml = newHtml.replaceAll("%FILESIZE%", fileSizeHuman);
$(document).find("p[class*='fileNameBannerTemp_" + identifier + "']").parent().remove();
$(newHtml.replaceAll("%FILENAME%", fileName)).insertAfter($(this));
$(newTooltip).insertAfter($(this).closest("div[class*='embedWrapper_']").parent());
let fileNameBanner = $(document).find("p[class*='fileNameBanner_" + identifier + "']");
let fileTooltip = $(document).find("div[class*='fileNameTooltip_" + identifier + "']");
let lineHeight = parseInt($(fileTooltip).css('line-height')); // get the line-height of the div in pixels
let height = $(fileTooltip).height(); // get the height of the div in pixels
let numLines = (height / lineHeight) - 1; // calculate the number of lines
if (numLines > 1) {
let curTop = parseInt($(fileTooltip).css("top"));
let newTop = (curTop - (lineHeight * (numLines - 1)));
$(fileTooltip).css({
top: newTop
});
}
var isSeeking = false;
$(this).on("play", function() {
$(fileNameBanner).parent().css({ opacity: 0, pointerEvents: 'none' });
})
.on("loadedmetadata", function() {
if (this.autoplay) {
$(fileNameBanner).parent().css({ opacity: 0, pointerEvents: 'none' });
}
})
.on("seeking", function() {
isSeeking = true;
})
.on("seeked", function() {
isSeeking = false;
})
.on("pause", function(e) {
if(!isSeeking) {
$(fileNameBanner).parent().css({ opacity: 1, pointerEvents: 'auto' });
} else {
e.preventDefault(); // Prevent the pause event from being triggered
}
})
.on("ended", function() {
$(fileNameBanner).parent().css({ opacity: 1, pointerEvents: 'auto' });
});
$(fileNameBanner).on("mouseenter", function() {
console.log("in");
$(fileTooltip).css({ opacity: 1, transform: 'scale(1)' });
}).on("mouseleave", function() {
console.log("out");
$(fileTooltip).css({ opacity: 0, transform: 'scale(0.98)' });
});
})
.catch(error => {
console.error('Error:', error);
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment