>demote @CwcvilleGuardian
  • Welcome. Registering and having your account be approved may take a while since there's only one guy checking and approving accounts and guestposts
  • Boards are being moved around and added. Leave feedback in this thread and let jannies move your threads

Your most wanted suggestions

  • Thread starter Thread starter Barry
  • Start date Start date
  • Featured

Barry

Jetpack Expert
Staff member
Joined
Apr 20, 2025
Messages
8,916
Making this thread to see what people want. Feel free to link your suggestion thread here so I can see it if you want. One of the things I'm thinking of doing is changing the look of the site to something nicer, maybe even potentially updating the logo (keeping pepe and buster obviously)

Site shit is currently a one man operation so please be patient with me
 
HELL YES ADD BILIBILI EMBEDS
I actually did it
1789555240439.png
JavaScript:
// ==UserScript==
// @name         Soyjak.forum Bilibili Embed
// @namespace    https://greasyfork.org/
// @version      1.0
// @description  Automatically embeds Bilibili videos (including bangumi episodes) as players
// @author       You
// @match        *://soyjak.forum/*
// @match        *://*.soyjak.forum/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    // Create a nice responsive player
    function createPlayer(src) {
        const wrapper = document.createElement('div');
        wrapper.className = 'bilibili-embed-wrapper';
        wrapper.style.cssText = `
            position: relative;
            width: 100%;
            max-width: 720px;
            aspect-ratio: 16 / 9;
            margin: 10px 0;
            background: #000;
            border-radius: 6px;
            overflow: hidden;
        `;

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.allowFullscreen = true;
        iframe.scrolling = 'no';
        iframe.frameBorder = '0';
        iframe.allow = 'fullscreen';
        iframe.style.cssText = `
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border: 0;
        `;

        wrapper.appendChild(iframe);
        return wrapper;
    }

    // Convert a Bilibili URL into a player src
    function getPlayerSrc(url) {
        try {
            const u = new URL(url);

            // Regular video: /video/BVxxxx or /video/avxxxx
            let match = u.pathname.match(/\/video\/(BV[\w]+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&bvid=${match[1]}&autoplay=0`;
            }

            match = u.pathname.match(/\/video\/av(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&aid=${match[1]}&autoplay=0`;
            }

            // Bangumi / episode: /bangumi/play/ep123456
            match = u.pathname.match(/\/bangumi\/play\/ep(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&episodeId=${match[1]}&autoplay=0`;
            }

            // Short links (b23.tv) – we can't resolve them without a network request,
            // so just skip for now
            return null;
        } catch (e) {
            return null;
        }
    }

    function processLinks(root = document) {
        const links = root.querySelectorAll('a[href*="bilibili.com"], a[href*="b23.tv"]');

        links.forEach(link => {
            // Skip if we already processed this link
            if (link.dataset.biliProcessed) return;
            link.dataset.biliProcessed = '1';

            const href = link.href;
            const playerSrc = getPlayerSrc(href);
            if (!playerSrc) return;

            // Replace the link with the player
            const player = createPlayer(playerSrc);

            // Try to put the player after the link (keeps the original text visible)
            // or replace the whole link if it's alone
            if (link.parentElement && link.parentElement.childNodes.length === 1) {
                link.parentElement.replaceChild(player, link);
            } else {
                link.after(player);
                // Optional: hide the original link text if you prefer
                // link.style.display = 'none';
            }
        });
    }

    // Run on page load
    processLinks();

    // Also watch for new posts loaded via AJAX (infinite scroll, quotes, etc.)
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            for (const node of mutation.addedNodes) {
                if (node.nodeType === 1) {
                    processLinks(node);
                }
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();
 
I actually did it
View attachment 169418
JavaScript:
// ==UserScript==
// @name         Soyjak.forum Bilibili Embed
// @namespace    https://greasyfork.org/
// @version      1.0
// @description  Automatically embeds Bilibili videos (including bangumi episodes) as players
// @author       You
// @match        *://soyjak.forum/*
// @match        *://*.soyjak.forum/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    // Create a nice responsive player
    function createPlayer(src) {
        const wrapper = document.createElement('div');
        wrapper.className = 'bilibili-embed-wrapper';
        wrapper.style.cssText = `
            position: relative;
            width: 100%;
            max-width: 720px;
            aspect-ratio: 16 / 9;
            margin: 10px 0;
            background: #000;
            border-radius: 6px;
            overflow: hidden;
        `;

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.allowFullscreen = true;
        iframe.scrolling = 'no';
        iframe.frameBorder = '0';
        iframe.allow = 'fullscreen';
        iframe.style.cssText = `
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border: 0;
        `;

        wrapper.appendChild(iframe);
        return wrapper;
    }

    // Convert a Bilibili URL into a player src
    function getPlayerSrc(url) {
        try {
            const u = new URL(url);

            // Regular video: /video/BVxxxx or /video/avxxxx
            let match = u.pathname.match(/\/video\/(BV[\w]+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&bvid=${match[1]}&autoplay=0`;
            }

            match = u.pathname.match(/\/video\/av(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&aid=${match[1]}&autoplay=0`;
            }

            // Bangumi / episode: /bangumi/play/ep123456
            match = u.pathname.match(/\/bangumi\/play\/ep(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&episodeId=${match[1]}&autoplay=0`;
            }

            // Short links (b23.tv) – we can't resolve them without a network request,
            // so just skip for now
            return null;
        } catch (e) {
            return null;
        }
    }

    function processLinks(root = document) {
        const links = root.querySelectorAll('a[href*="bilibili.com"], a[href*="b23.tv"]');

        links.forEach(link => {
            // Skip if we already processed this link
            if (link.dataset.biliProcessed) return;
            link.dataset.biliProcessed = '1';

            const href = link.href;
            const playerSrc = getPlayerSrc(href);
            if (!playerSrc) return;

            // Replace the link with the player
            const player = createPlayer(playerSrc);

            // Try to put the player after the link (keeps the original text visible)
            // or replace the whole link if it's alone
            if (link.parentElement && link.parentElement.childNodes.length === 1) {
                link.parentElement.replaceChild(player, link);
            } else {
                link.after(player);
                // Optional: hide the original link text if you prefer
                // link.style.display = 'none';
            }
        });
    }

    // Run on page load
    processLinks();

    // Also watch for new posts loaded via AJAX (infinite scroll, quotes, etc.)
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            for (const node of mutation.addedNodes) {
                if (node.nodeType === 1) {
                    processLinks(node);
                }
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();
We're back.
 
ask me for anymore sites needed
JavaScript:
// ==UserScript==
// @name         Soyjak.forum Video Embedder
// @namespace    https://greasyfork.org/
// @version      2.0
// @description  Auto-embeds Bilibili, Odysee, Rumble and BitChute videos
// @author       You
// @match        *://soyjak.forum/*
// @match        *://*.soyjak.forum/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    function createPlayer(src) {
        const wrapper = document.createElement('div');
        wrapper.className = 'custom-video-embed';
        wrapper.style.cssText = `
            position: relative;
            width: 100%;
            max-width: 720px;
            aspect-ratio: 16 / 9;
            margin: 12px 0;
            background: #000;
            border-radius: 6px;
            overflow: hidden;
        `;

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.allowFullscreen = true;
        iframe.scrolling = 'no';
        iframe.frameBorder = '0';
        iframe.allow = 'fullscreen; autoplay; encrypted-media';
        iframe.style.cssText = `
            position: absolute;
            top: 0; left: 0;
            width: 100%; height: 100%;
            border: 0;
        `;

        wrapper.appendChild(iframe);
        return wrapper;
    }

    function getPlayerSrc(url) {
        try {
            const u = new URL(url);
            const host = u.hostname.replace(/^www\./, '');
            const path = u.pathname;

            // ===== Bilibili =====
            if (host.includes('bilibili.com')) {
                let m = path.match(/\/video\/(BV[\w]+)/i);
                if (m) return `https://player.bilibili.com/player.html?isOutside=true&bvid=${m[1]}&autoplay=0`;

                m = path.match(/\/video\/av(\d+)/i);
                if (m) return `https://player.bilibili.com/player.html?isOutside=true&aid=${m[1]}&autoplay=0`;

                m = path.match(/\/bangumi\/play\/ep(\d+)/i);
                if (m) return `https://player.bilibili.com/player.html?isOutside=true&episodeId=${m[1]}&autoplay=0`;
            }

            // ===== Odysee =====
            if (host === 'odysee.com') {
                // Already an embed link
                if (path.startsWith('/$/embed/')) {
                    return url;
                }
                // Normal claim URL → convert to embed
                // Example: /@channel/video:hash  or  /video:hash
                const claim = path.replace(/^\/+/, '');
                if (claim) {
                    return `https://odysee.com/$/embed/${claim}`;
                }
            }

            // ===== Rumble =====
            if (host === 'rumble.com') {
                // Already an embed
                let m = path.match(/\/embed\/([a-z0-9.]+)/i);
                if (m) {
                    return `https://rumble.com/embed/${m[1]}/`;
                }

                // Normal video page: /vXXXXX-title.html  or  /vXXXXX.html
                m = path.match(/\/(v[a-z0-9]+)(?:-|\.|$)/i);
                if (m) {
                    return `https://rumble.com/embed/${m[1]}/`;
                }
            }

            // ===== BitChute =====
            if (host === 'bitchute.com') {
                // Already embed
                let m = path.match(/\/embed\/([^\/\?]+)/i);
                if (m) {
                    return `https://www.bitchute.com/embed/${m[1]}/`;
                }

                // Normal video page
                m = path.match(/\/video\/([^\/\?]+)/i);
                if (m) {
                    return `https://www.bitchute.com/embed/${m[1]}/`;
                }
            }

            return null;
        } catch (e) {
            return null;
        }
    }

    function processLinks(root = document) {
        const selectors = [
            'a[href*="bilibili.com"]',
            'a[href*="odysee.com"]',
            'a[href*="rumble.com"]',
            'a[href*="bitchute.com"]'
        ].join(',');

        const links = root.querySelectorAll(selectors);

        links.forEach(link => {
            if (link.dataset.embedProcessed) return;
            link.dataset.embedProcessed = '1';

            const playerSrc = getPlayerSrc(link.href);
            if (!playerSrc) return;

            const player = createPlayer(playerSrc);

            // Put player after the link (keeps original text)
            link.after(player);
        });
    }

    // Initial run
    processLinks();

    // Watch for new content (AJAX posts, infinite scroll, etc.)
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            for (const node of mutation.addedNodes) {
                if (node.nodeType === 1) {
                    processLinks(node);
                }
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();
 
I actually did it
View attachment 169418
JavaScript:
// ==UserScript==
// @name         Soyjak.forum Bilibili Embed
// @namespace    https://greasyfork.org/
// @version      1.0
// @description  Automatically embeds Bilibili videos (including bangumi episodes) as players
// @author       You
// @match        *://soyjak.forum/*
// @match        *://*.soyjak.forum/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    // Create a nice responsive player
    function createPlayer(src) {
        const wrapper = document.createElement('div');
        wrapper.className = 'bilibili-embed-wrapper';
        wrapper.style.cssText = `
            position: relative;
            width: 100%;
            max-width: 720px;
            aspect-ratio: 16 / 9;
            margin: 10px 0;
            background: #000;
            border-radius: 6px;
            overflow: hidden;
        `;

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.allowFullscreen = true;
        iframe.scrolling = 'no';
        iframe.frameBorder = '0';
        iframe.allow = 'fullscreen';
        iframe.style.cssText = `
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border: 0;
        `;

        wrapper.appendChild(iframe);
        return wrapper;
    }

    // Convert a Bilibili URL into a player src
    function getPlayerSrc(url) {
        try {
            const u = new URL(url);

            // Regular video: /video/BVxxxx or /video/avxxxx
            let match = u.pathname.match(/\/video\/(BV[\w]+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&bvid=${match[1]}&autoplay=0`;
            }

            match = u.pathname.match(/\/video\/av(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&aid=${match[1]}&autoplay=0`;
            }

            // Bangumi / episode: /bangumi/play/ep123456
            match = u.pathname.match(/\/bangumi\/play\/ep(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&episodeId=${match[1]}&autoplay=0`;
            }

            // Short links (b23.tv) – we can't resolve them without a network request,
            // so just skip for now
            return null;
        } catch (e) {
            return null;
        }
    }

    function processLinks(root = document) {
        const links = root.querySelectorAll('a[href*="bilibili.com"], a[href*="b23.tv"]');

        links.forEach(link => {
            // Skip if we already processed this link
            if (link.dataset.biliProcessed) return;
            link.dataset.biliProcessed = '1';

            const href = link.href;
            const playerSrc = getPlayerSrc(href);
            if (!playerSrc) return;

            // Replace the link with the player
            const player = createPlayer(playerSrc);

            // Try to put the player after the link (keeps the original text visible)
            // or replace the whole link if it's alone
            if (link.parentElement && link.parentElement.childNodes.length === 1) {
                link.parentElement.replaceChild(player, link);
            } else {
                link.after(player);
                // Optional: hide the original link text if you prefer
                // link.style.display = 'none';
            }
        });
    }

    // Run on page load
    processLinks();

    // Also watch for new posts loaded via AJAX (infinite scroll, quotes, etc.)
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            for (const node of mutation.addedNodes) {
                if (node.nodeType === 1) {
                    processLinks(node);
                }
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();
Make some more userscripts and cobble them all together into a script with toggles out of it. A “Shroom+” is you will…
 
Also add a reply quote button to profile posts the bb code already works
JavaScript:
// ==UserScript==
// @name         XenForo Profile Post Quote Button
// @namespace    https://greasyfork.org/
// @version      1.7
// @description  Proper Quote button for profile posts
// @author       You
// @match        *://soyjak.forum/*
// @match        *://*.soyjak.forum/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    function addQuoteButtons() {
        document.querySelectorAll('a').forEach(link => {
            const text = (link.textContent || '').trim().toLowerCase();
            const href = (link.getAttribute('href') || '').toLowerCase();

            if (!text.includes('report') && !href.includes('report')) return;
            if (link.dataset.quoteAdded) return;

            const post = link.closest('.message, .messageSimple, .message--profilePost, li, article, .block-row');
            if (!post) return;
            if (post.dataset.quoteProcessed) return;

            link.dataset.quoteAdded = '1';
            post.dataset.quoteProcessed = '1';

            // Username
            const userEl = post.querySelector('a.username, .username, .message-name a, .messageSimple-name a');
            const username = userEl ? userEl.textContent.trim() : 'User';

            // Try to get a clean message body only
            let contentEl = post.querySelector('.bbWrapper');
            if (!contentEl) contentEl = post.querySelector('.message-content .bbWrapper, .messageSimple-content .bbWrapper');
            if (!contentEl) contentEl = post.querySelector('.message-content, .messageSimple-content, .message-body');

            let content = '';
            if (contentEl) {
                // Clone so we can remove unwanted parts
                const clone = contentEl.cloneNode(true);

                // Remove timestamps, attribution, post numbers, etc.
                clone.querySelectorAll(
                    '.message-attribution, .message-attribution-main, .message-attribution-opposite, ' +
                    '.message-userDetails, time, .DateTime, .u-dt, .message-header, ' +
                    '.message-footer, .actionBar, .message-actionBar, .reactionsBar'
                ).forEach(el => el.remove());

                content = clone.innerText.trim();
            }

            if (!content) return;

            // Create button
            const btn = document.createElement('a');
            btn.href = 'javascript:;';
            btn.textContent = 'Quote';
            btn.className = link.className;
            btn.style.marginLeft = '10px';
            btn.style.cursor = 'pointer';
            btn.title = 'Quote this profile post';

            let hasRun = false;

            btn.addEventListener('click', function (e) {
                e.preventDefault();
                e.stopPropagation();
                if (hasRun) return;
                hasRun = true;

                // Click real Reply button to open the box
                const replyBtn = post.querySelector(
                    'a[href*="reply"], a.actionBar-action--reply, a[data-xf-click*="reply"], a[title*="Reply" i]'
                );
                if (replyBtn) replyBtn.click();

                setTimeout(() => {
                    let editor = post.querySelector('textarea[name="message"], .fr-element[contenteditable="true"], textarea.js-editor');
                    if (!editor) {
                        editor = document.querySelector('.message-responseRow textarea, .js-quickReply textarea, textarea[name="message"], .fr-element[contenteditable="true"]');
                    }

                    if (editor) {
                        // Clean quote format
                        const quote = `[QUOTE="${username}"]\n${content}\n[/QUOTE]\n\n`;

                        if (editor.isContentEditable) {
                            editor.innerHTML = '';
                            editor.focus();
                            document.execCommand('insertText', false, quote);
                        } else {
                            editor.value = quote;
                            editor.focus();
                            editor.dispatchEvent(new Event('input', { bubbles: true }));
                        }

                        editor.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    }

                    setTimeout(() => { hasRun = false; }, 1000);
                }, 450);
            });

            link.parentNode.insertBefore(btn, link.nextSibling);
        });
    }

    addQuoteButtons();

    const observer = new MutationObserver(addQuoteButtons);
    observer.observe(document.body, { childList: true, subtree: true });
})();
 
I actually did it
View attachment 169418
JavaScript:
// ==UserScript==
// @name         Soyjak.forum Bilibili Embed
// @namespace    https://greasyfork.org/
// @version      1.0
// @description  Automatically embeds Bilibili videos (including bangumi episodes) as players
// @author       You
// @match        *://soyjak.forum/*
// @match        *://*.soyjak.forum/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    // Create a nice responsive player
    function createPlayer(src) {
        const wrapper = document.createElement('div');
        wrapper.className = 'bilibili-embed-wrapper';
        wrapper.style.cssText = `
            position: relative;
            width: 100%;
            max-width: 720px;
            aspect-ratio: 16 / 9;
            margin: 10px 0;
            background: #000;
            border-radius: 6px;
            overflow: hidden;
        `;

        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.allowFullscreen = true;
        iframe.scrolling = 'no';
        iframe.frameBorder = '0';
        iframe.allow = 'fullscreen';
        iframe.style.cssText = `
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border: 0;
        `;

        wrapper.appendChild(iframe);
        return wrapper;
    }

    // Convert a Bilibili URL into a player src
    function getPlayerSrc(url) {
        try {
            const u = new URL(url);

            // Regular video: /video/BVxxxx or /video/avxxxx
            let match = u.pathname.match(/\/video\/(BV[\w]+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&bvid=${match[1]}&autoplay=0`;
            }

            match = u.pathname.match(/\/video\/av(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&aid=${match[1]}&autoplay=0`;
            }

            // Bangumi / episode: /bangumi/play/ep123456
            match = u.pathname.match(/\/bangumi\/play\/ep(\d+)/i);
            if (match) {
                return `https://player.bilibili.com/player.html?isOutside=true&episodeId=${match[1]}&autoplay=0`;
            }

            // Short links (b23.tv) – we can't resolve them without a network request,
            // so just skip for now
            return null;
        } catch (e) {
            return null;
        }
    }

    function processLinks(root = document) {
        const links = root.querySelectorAll('a[href*="bilibili.com"], a[href*="b23.tv"]');

        links.forEach(link => {
            // Skip if we already processed this link
            if (link.dataset.biliProcessed) return;
            link.dataset.biliProcessed = '1';

            const href = link.href;
            const playerSrc = getPlayerSrc(href);
            if (!playerSrc) return;

            // Replace the link with the player
            const player = createPlayer(playerSrc);

            // Try to put the player after the link (keeps the original text visible)
            // or replace the whole link if it's alone
            if (link.parentElement && link.parentElement.childNodes.length === 1) {
                link.parentElement.replaceChild(player, link);
            } else {
                link.after(player);
                // Optional: hide the original link text if you prefer
                // link.style.display = 'none';
            }
        });
    }

    // Run on page load
    processLinks();

    // Also watch for new posts loaded via AJAX (infinite scroll, quotes, etc.)
    const observer = new MutationObserver(mutations => {
        for (const mutation of mutations) {
            for (const node of mutation.addedNodes) {
                if (node.nodeType === 1) {
                    processLinks(node);
                }
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();
>Shroom+
Bad omens lie here
 
Back
Top Bottom