Created
October 8, 2024 23:43
-
-
Save dvingerh/2b3e853af745aeef6852499287f68b44 to your computer and use it in GitHub Desktop.
discord.restorevideotitle.user.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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