Popup for toast
Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.sleazyfork.org/scripts/578336/1841909/Bs%20ToastPopup.js
// ==UserScript==
// @name Bsodergren Library
// @version 1.7.0
// @grant GM_xmlhttpRequest
// @grant nsafeWindow
// @license MIT
// @namespace https://greasyfork.org/users/984905
// ==/UserScript==
function showToast(message, duration = 3000, cmdElement = null) {
// Create toast container if it doesn't exist
let container = document.getElementById('tm-toast-container');
if (!container) {
container = document.createElement('div');
container.id = 'tm-toast-container';
container.style.position = 'fixed';
container.style.top = '20px';
container.style.left = '20px';
container.style.zIndex = '999999';
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.gap = '10px';
document.body.appendChild(container);
}
// Create toast element
const toast = document.createElement('div');
toast.textContent = message;
toast.style.background = 'rgb(0, 0, 0)';
toast.style.color = '#fff';
toast.style.padding = '10px 16px';
toast.style.borderRadius = '6px';
toast.style.borderColor = 'white';
toast.style.borderWidth = '3px';
toast.style.borderStyle = 'double';
toast.style.fontSize = '18px';
toast.style.boxShadow = '0 2px 8px rgba(0,0,0,0.3)';
toast.style.opacity = '0.5';
toast.style.transition = 'opacity 0.3s ease';
container.appendChild(toast);
// Fade in
requestAnimationFrame(() => {
toast.style.opacity = '1';
});
// Remove after duration
setTimeout(() => {
toast.style.opacity = '0';
toast.addEventListener('transitionend', () => {
toast.remove();
if (cmdElement !== null) {
cmdElement();
}
});
}, duration);
}
function waitForElement(selector, callback) {
const observer = new MutationObserver(() => {
const element = document.querySelector(selector);
if (element) {
observer.disconnect(); // Stop observing
callback(element);
}
});
// Observe changes in the entire document
observer.observe(document.body, {
childList: true,
subtree: true,
});
}
function jsonToUrlEncoded(jsonObj) {
if (typeof jsonObj !== 'object' || jsonObj === null) {
throw new Error('Input must be a non-null object');
}
return Object.keys(jsonObj)
.map(
key => encodeURIComponent(key) + '=' + encodeURIComponent(jsonObj[key])
)
.join('&');
}
function saveToLocalServer(postUrl, data, toast, command = null) {
postUrl = 'http://media.lan/plex/' + postUrl;
const encoded = jsonToUrlEncoded(data);
GM_xmlhttpRequest({
method: 'POST',
url: postUrl,
data: encoded,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
responseType: 'document',
onload: function (response) {
var responseXML = response.responseXML;
if (!responseXML) {
try {
responseXML = new DOMParser().parseFromString(
response.responseText,
'text/html'
);
} catch (err) { }
}
showToast(response.responseText, 3000, command);
},
});
}