- // ==UserScript==
- // @name Discord - Custom Background Image
- // @namespace http://tampermonkey.net/
- // @version 0.9
- // @description You can set custom background image of Discord
- // @author You
- // @match https://discord.com/channels/*
- // @match https://discord.com/channels/*/*
- // @icon https://www.google.com/s2/favicons?domain=discord.com
- // @grant GM.xmlHttpRequest
- // @grant GM.registerMenuCommand
- // @grant GM.getValue
- // @grant GM.setValue
- // @grant GM.addElement
- // @connect i.imgur.com
- // @license MIT
- // ==/UserScript==
-
- (async window => {
- 'use strict';
-
- let intervalTime = 30 * 1000;
- let urls = [
- 'https://i.imgur.com/cHKbKQT.jpeg',
- 'https://i.imgur.com/sqmqy20.png',
- 'https://i.imgur.com/cCL6TPk.jpeg',
- 'https://i.imgur.com/Z6GYpxh.jpeg',
- 'https://i.imgur.com/FNJdY5h.jpeg',
- 'https://i.imgur.com/uKVG1XM.jpeg'
- ];
-
- let g_elm = null;
-
- const del = () => {
- if (g_elm) {
- g_elm.remove();
- g_elm = null;
- return true;
- }
- return false;
- };
-
- const addInput = async (value) => {
- if (del()) return;
-
- g_elm = await GM.addElement(document.body, 'div', {});
- Object.assign(g_elm.style, {
- 'position': 'fixed',
- 'width': '100vw',
- 'height': '100vh',
- 'display': 'flex',
- 'flex-wrap': 'wrap',
- 'justify-content': 'center',
- 'align-items': 'center',
- 'z-index': Infinity
- });
-
- const input = await GM.addElement(g_elm, 'textarea', {
- textContent: value
- });
-
- Object.assign(input.style, {
- 'width': '50vw',
- 'height': '30vh',
- 'font-size': '24px',
- 'font-weight': 'bold'
- });
-
- const btnSave = await GM.addElement(g_elm, 'button', {
- textContent: 'save'
- });
-
- await GM.addElement(g_elm, 'div', {
- textContent: ' '
- });
-
- const btnCancel = await GM.addElement(g_elm, 'button', {
- textContent: 'cancel'
- });
-
- for (const v of [btnSave, btnCancel]) {
- Object.assign(v.style, {
- 'color': 'white',
- 'backgroundColor': 'red'
- });
- }
-
- return new Promise((resolve, reject) => {
- btnSave.addEventListener('click', () => del() && resolve(input.value));
- btnCancel.addEventListener('click', () => del() && reject());
- });
- };
-
- const key1 = 'intervalTime';
- GM.registerMenuCommand('config interval time', async () => {
- const res = await addInput(await GM.getValue(key1, intervalTime));
- if (!res) return;
-
- const m = res.match(/[0-9]+/);
- if (!m) return;
-
- const n = Number(m[0]);
- intervalTime = n;
- GM.setValue(key1, n);
- });
-
- intervalTime = await GM.getValue(key1, intervalTime);
-
- const key2 = 'URL';
- GM.registerMenuCommand('config URL', async () => {
- const res = await addInput(await GM.getValue(key2, urls.join('\n')));
- if (!res) return;
-
- const a = findURL(res);
- if (!a.length) return;
-
- urls = a;
- GM.setValue(key2, a.join('\n'));
- });
-
- urls = (await GM.getValue(key2, urls.join('\n'))).split('\n');
-
- const findURL = (str) => {
- const m = str.match(/(https?|ftp)(:\/\/[-_.!~*'()a-zA-Z0-9;\/?:@&=+$,%#]+)/g);
- return m || [];
- };
-
- const memo = new Map();
- const get = async (url) => {
- if (memo.has(url)) return memo.get(url);
-
- const res = await GM.xmlHttpRequest({
- method: 'GET',
- url: url,
- withCredentials: true,
- responseType: 'arraybuffer',
- });
-
- const blobUrl = URL.createObjectURL(new Blob([res.response], { type: 'application/octet-binary' }));
- memo.set(url, blobUrl);
-
- return blobUrl;
- };
-
- let g_url = await get(urls[0]);
-
- const wait = (resolve) => {
- if (document.querySelector('[class^="chatContent"]')) return resolve();
- setTimeout(() => wait(resolve), 500);
- };
-
- await new Promise(resolve => wait(resolve));
-
- const setURL = () => {
- Object.assign(document.body.children[0].style, {
- 'background-image': 'url("' + g_url + '")',
- 'background-attachment': 'fixed',
- 'background-position': 'center center',
- 'background-size': 'cover',
- 'background-repeat': 'no-repeat',
- 'transition-duration': '1.5s'
- });
- };
-
- setURL();
-
- const setOther = () => {
- for (const v of document.querySelectorAll('*')) {
- v.style.backgroundColor = 'rgba(0, 0, 0, 0)';
- }
- document.body.children[0].children[3].style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
-
- const aplicarTransparencia = () => {
- const embeds = document.querySelectorAll('.embed');
- embeds.forEach(embed => {
- embed.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
- embed.style.backdropFilter = 'blur(10px)';
- });
-
- const embedContents = document.querySelectorAll('.embed .embed-content');
- embedContents.forEach(content => {
- content.style.backgroundColor = 'rgba(0, 0, 0, 0.3)';
- });
-
- const attachments = document.querySelectorAll('.attachment');
- attachments.forEach(attachment => {
- attachment.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
- attachment.style.backdropFilter = 'blur(10px)';
- });
- };
-
- const observeEmbeds = () => {
- const observer = new MutationObserver(mutations => {
- aplicarTransparencia();
- });
-
- observer.observe(document.body, { childList: true, subtree: true });
-
- setInterval(() => {
- aplicarTransparencia();
- }, 50); // Verificação a cada 50ms
- };
-
- observeEmbeds();
-
- aplicarTransparencia();
- };
-
- setOther();
-
- let _url = location.href;
- let _time = 0;
- let index = 0;
-
- const update = async () => {
- const time = performance.now();
-
- if (time - _time > intervalTime) {
- g_url = await get(urls[(++index) % urls.length]);
- _time = performance.now();
- setURL();
- } else {
- const url = location.href;
- if (url !== _url) {
- _url = url;
- setOther();
- }
- }
-
- requestAnimationFrame(update);
- };
-
- update();
- })(window.unsafeWindow || window);