Camwhores.tv Utilities Mod

Information preview inside messages, removal of private lock from videos uploaded by friends, and more

// ==UserScript==
// @name         Camwhores.tv Utilities Mod
// @namespace    https://sleazyfork.org/users/1281730-vipprograms
// @version      1.3.0
// @description  Information preview inside messages, removal of private lock from videos uploaded by friends, and more
// @author       vipprograms
// @match        https://www.camwhores.tv/*
// @grant        GM_xmlhttpRequest
// @grant        GM.getValue
// @grant        GM_getValue
// @grant        GM.setValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @grant        GM.registerMenuCommand
// @grant        window.close
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAMUExURQAAAP8ANwwA/////7gbQJkAAAABdFJOUwBA5thmAAAAAWJLR0QDEQxM8gAAAAd0SU1FB+gDHhIuCjXV/h8AAAA4SURBVAjXY2ANDQ1gEA0NDWEIYWBgZAhgAAIUghEiC1YHBhpMDRpIhBbXghUMXKtWLWBgWqHVAACjlwz/pN0YPwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyNC0wMy0zMFQxODo0NjowOSswMDowME+iXNIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjQtMDMtMzBUMTg6NDY6MDkrMDA6MDA+/+RuAAAAKHRFWHRkYXRlOnRpbWVzdGFtcAAyMDI0LTAzLTMwVDE4OjQ2OjEwKzAwOjAwMNiA/AAAAABJRU5ErkJggg==
// @require      https://code.jquery.com/jquery-3.7.1.slim.min.js
// ==/UserScript==

(function() {
    'use strict';

    var _GM_registerMenuCommand, options;
    const refreshMessagesTimer = 2500;

    function isArrayEmpty(arr) {
        return arr.length === 0;
    }
    function retrieveValueFromStorage(key) {
        if (typeof GM_setValue === "function") {
            return GM_getValue(key, false); // Default value set to false for boolean
        }
        else if (typeof GM === "object" && typeof GM.getValue === "function" && typeof GM.setValue === "function") {
            return GM.getValue(key, false).then(function(value) {
                return value;
            });
        }
        else {
            console.error("Unsupported userscript manager.");
            return undefined;
        }
    }

    function saveValue(key, array) {
        GM.setValue(key, array).then(function() {
            console.log("Array saved successfully.");
        }).catch(function(error) {
            console.error("Error saving array:", error);
        });
    }

    if (typeof GM_registerMenuCommand !== 'undefined') {
        _GM_registerMenuCommand = GM_registerMenuCommand;
    } else if (typeof GM !== 'undefined' && typeof GM.registerMenuCommand !== 'undefined') {
        _GM_registerMenuCommand = GM.registerMenuCommand;
    } else {
        _GM_registerMenuCommand = (s, f) => { debug(s); debug(f); };
    }

    function toggleChange(options, optionName, defaultValue = false){
        var updatedOptions;
        var currentState = options[optionName] !== undefined ? options[optionName] : defaultValue;
        _GM_registerMenuCommand((currentState ? "Disable " : "Enable ") + optionName, () => {
            currentState = !currentState;
            updatedOptions[optionName] = currentState;
            saveValue("options", updatedOptions);

            setTimeout(() => {
                location.reload();
            }, 500);
        });

        updatedOptions = retrieveValueFromStorage("options") || {}; // Ensure options exist
        if (updatedOptions[optionName] === undefined) {
            updatedOptions[optionName] = defaultValue;
            saveValue("options", updatedOptions);
        }
    }

    function createForm(array_name, delimitedString){
        return new Promise((resolve, reject) => {
            var form = document.createElement('form');
            form.classList.add('form-container');

            var textBox = document.createElement('textarea');
            textBox.classList.add('textarea-input');
            textBox.setAttribute('autofocus', 'autofocus');


            var buttonsLine = document.createElement('div');
            buttonsLine.classList.add('buttons-line');

            var submitButton = document.createElement('button');
            submitButton.type = 'submit';
            submitButton.textContent = 'Submit';
            submitButton.classList.add('submit-button');

            var cancelButton = document.createElement('button');
            cancelButton.type = 'button';
            cancelButton.textContent = 'Cancel';
            cancelButton.classList.add('cancel-button');
            cancelButton.addEventListener('click', function() {
                document.body.removeChild(form);
                reject('Form cancelled');
            });

            window.addEventListener('click', function(event) {
                if (document.body.contains(form) && !form.contains(event.target)) {
                    document.body.removeChild(form);
                    reject('Form cancelled');
                }
            });

            textBox.value = delimitedString;

            form.appendChild(textBox);
            form.appendChild(buttonsLine);
            buttonsLine.appendChild(cancelButton);
            buttonsLine.appendChild(submitButton);

            document.body.appendChild(form);

            form.addEventListener('submit', function(event){
                event.preventDefault();
                var inputValue = textBox.value.split('\n').map(line => line.trim()).filter(line => line !== '');
                document.body.removeChild(form);
                resolve(inputValue);
            });
        });
    }


    function optionsArrayEditor(array_name, optionsKeyLegible){

        _GM_registerMenuCommand("Change " + optionsKeyLegible[array_name], () => {
            var originalArray = retrieveValueFromStorage(array_name);
            var delimitedString = originalArray.join("\n");

            createForm(array_name, delimitedString).then(lines => {
                saveValue(array_name, lines);
            });

        });
    }

function optionsStringEditor(string_name, optionsKeyLegible) {
    _GM_registerMenuCommand("Change " + optionsKeyLegible[string_name], () => {
        var originalString = retrieveValueFromStorage(string_name);
        createForm(string_name, originalString).then(lines => {
            // Convert array 'lines' to a string by joining values with '\n'
            let stringifiedLines = lines.join('\n');
            saveValue(string_name, stringifiedLines);
        });

    });
}


    options = retrieveValueFromStorage("options")
    toggleChange(options, "auto close window after friend confirm")
    var closeWindowReject = retrieveValueFromStorage("options")["auto close window after friend reject"];

    toggleChange(options, "auto close window after friend reject")
    var closeWindowConfirm = retrieveValueFromStorage("options")["auto close window after friend confirm"];

    toggleChange(options, "alternative thumbnails", true)
    var altThumbs = retrieveValueFromStorage("options")["alternative thumbnails"];

    toggleChange(options, "auto refresh message page", true)
    var refreshMessagePage = retrieveValueFromStorage("options")["auto refresh message page"];

    const auto_replies_default = ["Next time you send me a request with 0 videos, I'll block you",
                                  "Very nice videos",
                                  "Why? What's wrong?",
                                  "Sorry, I don't like your videos",
                                  "You don't have any videos"];
    const highlight_keywords_default = ['joi', 'cei', 'fuck', "cumshot"];
    const friend_request_text_default = "Hi! I'm interested in this video:";


    var auto_replies = retrieveValueFromStorage("auto_replies");
    var highlight_keywords = retrieveValueFromStorage("highlight_keywords");
    var friend_request_text = retrieveValueFromStorage("friend_request_text");

    if (!auto_replies) {
        auto_replies = auto_replies_default;
        saveValue("auto_replies", auto_replies_default);
    }
    if (!highlight_keywords) {
        highlight_keywords = highlight_keywords_default;
        saveValue("highlight_keywords", highlight_keywords_default);
    }
    if (!friend_request_text) {
        friend_request_text = friend_request_text_default;
        saveValue("friend_request_text", friend_request_text_default);
    }

    var optionsKeyLegible = {
      auto_replies: "template replies",
      highlight_keywords: "highlight keywords",
      friend_request_text: "friend requests text"
    }
    optionsArrayEditor("auto_replies", optionsKeyLegible)
    optionsArrayEditor("highlight_keywords", optionsKeyLegible)
    optionsStringEditor("friend_request_text", optionsKeyLegible)



    const style = document.createElement('style');
    style.textContent = `

      ul > li.next,
      ul > li.prev {
        display: list-item !important;
      }
       .item:hover > a > div.img > .friends-tag,
       .item:hover > a > div.img > .videos-tag{
        background-color:#1a1a1a !important;
      }
      .button{
        color: rgb(183, 176, 167);
        text-align: center;
        border: 1px solid transparent;
        font-size: 14px;
        padding: 5px 10px;
        cursor: pointer;
        background: linear-gradient(to bottom, #ffffff 0%, #cccccc 100%);
        border-radius: 3px;
        display: inline-block;
        margin: 0 .3rem .3rem 0;
        color: dimgrey;
      }
      .button:hover{
        color: #f56c08;
        border: 1px solid transparent;
        background: #1e1e1e;
      }
      div.img span.unread-notification{
        background: #c45606ab;
        backdrop-filter: blur(5px) brightness(1);
        top: 0px;
        left: 0px;
        border-bottom-left-radius: 3px;
        border-bottom-right-radius: 3px;
        outline: 3px solid #f56c08;
        animation: glow 5s infinite;
      }
      @keyframes glow {
        0% {
          outline-color: #f56c08d6;
        }
        50% {
          outline-color: transparent;
        }
        100% {
          outline-color: #f56c08d6;
        }
      }
    .form-container {
        box-sizing: border-box;
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        max-width: 100vw;
        width: 800px;
        padding: 2.5rem;
        border-radius: .25rem;
        z-index:99999;
        background-color: transparent !important;
        backdrop-filter: blur(1rem) brightness(.8) contrast(1.2)
    }
    .form-container * {
        box-sizing: inherit;
    }
    .textarea-input {
        width: 100%;
        min-height: 10rem;
        padding: 1rem;
        border-radius: .25rem;

        color-scheme: dark !important;
    }
    .buttons-line {
        margin-top: .3rem;
        gap:.3rem;
        width: 100%;
        display: flex;
    }
    .submit-button:hover, .cancel-button:hover{
      filter: brightness(.8) contrast(1.2)
    }
    .submit-button, .cancel-button{
      transform: .3s;
    }
    .submit-button {
        height: 50px;
        flex-grow: 1;
        cursor: pointer;
        border-radius: .25rem;
        color-scheme: dark !important;
        font-weight:bold;
        border:0;
    }
    .cancel-button {
        width:min-content;
        height: 50px;
        cursor: pointer;
        border-radius: .25rem;
        color-scheme: dark !important;
        background-color: red;
        font-weight:bold;
        padding-inline:.5rem;
        border:0;

    }

    `;
    document.head.appendChild(style);


    if ((window.location.href.endsWith("?action=reject_add_to_friends_done") && closeWindowReject) ||
        (window.location.href.endsWith("?action=confirm_add_to_friends_done") && closeWindowConfirm)) {
        window.close();
    }else  if (window.location.href == "https://www.camwhores.tv/my/messages/") {

        // console.log('(window.location.href == "https://www.camwhores.tv/my/messages/")')
        if(refreshMessagePage){
            $(document).ready(function() {
                var linkClicked = localStorage.getItem("linkClicked") === "true";
                console.log("Initial linkClicked value:", linkClicked);

                $(window).on("focus", function() {
                    localStorage.setItem("linkClicked", "false");
                    linkClicked = false;
                    console.log("Window is focused");
                    if (interval !== null) {
                        clearInterval(interval);
                    }
                });

                if (linkClicked) {
                        console.log("Reloading...");
                        var interval = setInterval(function() {
                            location.reload();
                        }, refreshMessagesTimer);
                }

                $(document).on("click auxclick", "a", function(event) {
                    var href = $(this).attr("href");
                    if (event.button === 0 || event.button === 1) {
                        // alert("You're trying to go to " + href);
                        localStorage.setItem("linkClicked", "true");
                        linkClicked = true;
                        console.log("Link clicked. Will refresh");
                    }
                });

                $(window).on("blur", function() {
                    console.log("Window blur event");
                    if (linkClicked) {
                        console.log("Reloading...");
                        var interval = setInterval(function() {
                            location.reload();
                        }, refreshMessagesTimer);
                    }
                });


            });

        }




        function processThumbnails() {
            // console.log("Processing thumbnails");
            var thumbnails = document.querySelectorAll('strong.title');
            if (thumbnails.length === 0) {
                console.log("Thumbnails not found. Retrying in 1000 milliseconds.");
                setTimeout(function() {
                    processThumbnails(); // Retry processing thumbnails
                }, 1000);
                return false; // Return false if thumbnails not found
            }

            thumbnails.forEach(function(thumbnail) {
                var usernameText = thumbnail.textContent.trim();
                if (usernameText) {
                    var usernameLink = document.querySelector('a[title="' + usernameText + '"]');
                    if (usernameLink) {
                        var href = usernameLink.getAttribute('href');
                        var userIdMatch = href.match(/\/(\d+)\/$/);
                        if (userIdMatch && userIdMatch.length > 1) {
                            var userId = userIdMatch[1];
                            var usernameUrl = "https://www.camwhores.tv/members/" + userId + "/";
                            GM_xmlhttpRequest({
                                method: "GET",
                                url: usernameUrl,
                                onload: function(response) {
                                    var parser = new DOMParser();
                                    var htmlDoc = parser.parseFromString(response.responseText, "text/html");
                                    var infoMessage = htmlDoc.querySelector('.info-message');
                                    var usernameLink = document.querySelector('a[title="' + usernameText + '"]');
                                    // console.log(usernameText + ": " + usernameUrl)
                                    // console.log(usernameLink)
                                    if (infoMessage && infoMessage.textContent.includes("is in your friends list.")) {
                                        if (usernameLink) {
                                            var divElement = document.createElement('div');
                                            divElement.classList.add("friends-tag");
                                            divElement.textContent = "Friends ✅";
                                            divElement.style.position = "absolute";
                                            divElement.style.top = "0";
                                            divElement.style.right = "0";
                                            divElement.style.backgroundColor = "#414141"; //#1a1a1a
                                            divElement.style.borderBottomLeftRadius = "3px";
                                            divElement.style.color = "white";
                                            divElement.style.padding = "3px 5px";

                                            if (usernameLink) {
                                                var firstDivElement = usernameLink.querySelector('div.img');
                                                if (firstDivElement) {
                                                    firstDivElement.appendChild(divElement);
                                                }
                                            }
                                        }
                                    }
                                    if(infoMessage && infoMessage.textContent.includes("wants to be your friend.")){
                                        divElement = document.createElement('div');
                                        divElement.textContent = "👀";
                                        divElement.title = "Wants to be your friend!";
                                        divElement.style.position = "absolute";
                                        divElement.style.bottom = "0";
                                        divElement.style.left = "0";
                                        // divElement.style.backgroundColor = "aquamarine";
                                        divElement.style.color = "white";
                                        divElement.style.fontSize = "1rem";
                                        divElement.style.padding = ".5rem .25rem";

                                        if (usernameLink) {
                                            firstDivElement = usernameLink.querySelector('div.img');
                                            if (firstDivElement) {
                                                firstDivElement.appendChild(divElement);
                                            }
                                        }
                                    }

                                    var titleVideosElement = htmlDoc.evaluate('//*[@id="list_videos_uploaded_videos"]/div[1]/h2', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                                    var videoNumber = 0;

                                    if (titleVideosElement && titleVideosElement.singleNodeValue) {
                                        var titleVideosText = titleVideosElement.singleNodeValue.textContent;
                                        if (titleVideosText) {
                                            var matches = titleVideosText.match(/\(([^)]+)\)/);
                                            videoNumber = matches ? matches[1] : 0;
                                        }
                                    }

                                    if(videoNumber || videoNumber === 0){
                                        divElement = document.createElement('div');
                                        divElement.classList.add("videos-tag");
                                        divElement.textContent = videoNumber;
                                        divElement.style.position = "absolute";
                                        divElement.style.bottom = "0";
                                        divElement.style.right = "0";
                                        divElement.style.backgroundColor = "CadetBlue";
                                        divElement.style.color = "white";
                                        divElement.style.padding = "3px 5px";
                                        divElement.style.borderTopLeftRadius = "3px";
                                    }


                                    if (usernameLink) {
                                        firstDivElement = usernameLink.querySelector('div.img');
                                        if (firstDivElement) {
                                            firstDivElement.appendChild(divElement);
                                        }
                                    }
                                } // end httpGET reponse

                            });
                        } else {
                            console.log("User ID not found in href for:", usernameText);
                        }
                    } else {
                        console.log("Username link not found for:", usernameText);
                    }
                }




            });
            return true; // Return true if thumbnails processed successfully
        }

        // Function to add event listener to buttons
        function addButtonEventListener() {
            console.log("Adding event listener to buttons");
            document.addEventListener('click', function(event) {
                var target = event.target;
                if (target && target.matches('a[data-action="ajax"]')) {
                    // console.log("Button clicked");

                    const h2Element = document.querySelector('#list_members_my_conversations div.headline h2');
                    const initialText = h2Element.textContent.trim();
                    // console.log("Initial text: " + initialText);
                    const checkChangeInterval = setInterval(function() {
                        const h2Element = document.querySelector('#list_members_my_conversations div.headline h2');
                        const currentText = h2Element.textContent.trim();
                        // console.log("Current text: " + currentText);
                        if (currentText !== initialText) {
                            clearInterval(checkChangeInterval);
                            processThumbnails();
                        }
                    }, 100);
                }
            });
        }


        console.log("Calling functions to apply styles and process thumbnails");

        setTimeout(function() {
            processThumbnails();
            var thumbnailsProcessed = processThumbnails();
            if (!thumbnailsProcessed) {
                console.log("Processing thumbnails failed. Retrying in 1000 milliseconds.");
                setTimeout(function() {
                    processThumbnails(); // Retry processing thumbnails
                }, 1000);
            }
            addButtonEventListener();
        }, 1000);




        setInterval(function() {
            processThumbnails()
            console.log("Updating status of users")
        }, 3000);


        const refreshIcon = document.createElement('span');
        refreshIcon.innerHTML = '↻'; // Unicode for refresh icon
        refreshIcon.title = 'Refresh Utilities Mod';
        refreshIcon.style.cursor = 'pointer';
        refreshIcon.style.marginLeft = '10px'; // Adjust margin as needed
        refreshIcon.addEventListener('click', function() {
            processThumbnails()
            console.log('Refreshing...');
        });

        const h2Element = document.querySelector('#list_members_my_conversations .headline h2');
        console.log("adding..?")
        h2Element.appendChild(refreshIcon);




    }else if(window.location.href.startsWith("https://www.camwhores.tv/my/messages/")) {


document.addEventListener('keydown', function(event) {
  if (event.ctrlKey && event.key === 'Enter') {
    event.preventDefault();
    document.querySelector('#send_message_form input[type="submit"]').click();
  }
});





        // Function to fetch the URL and extract title, content, and joined date
        function fetchAndExtract(url) {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: function(response) {
                    // Parse the response text into a HTML document
                    var parser = new DOMParser();
                    var htmlDoc = parser.parseFromString(response.responseText, "text/html");

                    var titleElement = htmlDoc.evaluate('//*[@id="list_videos_uploaded_videos"]/div[1]/h2', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                    var contentElement = htmlDoc.evaluate('//*[@id="list_videos_uploaded_videos_items"]/div[1]/a/div[3]/div[1]/em', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                    var joinedDateElement = htmlDoc.evaluate('/html/body/div[2]/div[2]/div/div[2]/div[2]/div/div/div[1]/div[3]/em', htmlDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                    var joinedDateText = joinedDateElement.singleNodeValue.textContent;
                    var confirmButton = document.querySelector('input[name="confirm"]');
                    var rejectButton = document.querySelector('input[name="reject"]');

                    if (titleElement && titleElement.singleNodeValue && contentElement && contentElement.singleNodeValue && joinedDateElement && joinedDateElement.singleNodeValue) {
                        var titleText = titleElement.singleNodeValue.textContent;
                        var extractedTitle = titleText.match(/\(([^)]+)\)/);
                        if (extractedTitle && extractedTitle.length > 1) {
                          // THERE ARE VIDEOS
                            confirmButton.style.backgroundImage = 'linear-gradient(rgb(0, 128, 0) 0%, rgb(0, 255, 0) 100%)';
                            confirmButton.style.color = '#fff';

                            var contentText = contentElement.singleNodeValue.textContent;
                            var generatedText = "<div id=gen_joined_text>Joined " + joinedDateText + "<br>" + extractedTitle[1] + " videos, last " + contentText + "</div>";
                            // Add generated text to the visible page
                            var messageDiv = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                            if (messageDiv && messageDiv.singleNodeValue) {
                                messageDiv.singleNodeValue.innerHTML += generatedText;
                            }
                        } else {
                            console.log('Text inside parentheses in title not found.');
                        }
                    } else {
                        // THERE ARE NO VIDEOS
                        console.log('Title, content, or joined date element not found. Probably no videos uploaded yet.');
                        rejectButton.style.backgroundImage = 'linear-gradient(rgb(255, 0, 0) 0%, rgb(128, 0, 0) 100%)';
                        rejectButton.style.color = '#fff';
                        messageDiv = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
                        if (messageDiv && messageDiv.singleNodeValue) {
                            messageDiv.singleNodeValue.innerHTML += "<div id=gen_joined_text>Joined " + joinedDateText + "<br><b>No videos</b></div>";
                        }
                    }
                }
            });









        }





        var bottomDiv = document.querySelector("#send_message_form > div > div.bottom");
        var responsesDiv = document.createElement("div");
        responsesDiv.id = "responses";
        responsesDiv.style.marginTop = "1rem";
        bottomDiv.insertAdjacentElement('afterend', responsesDiv);

        var textarea = document.querySelector("#send_message_message");

        auto_replies.forEach(function(string) {
            var button = document.createElement("button");
            button.textContent = string;
            button.classList.add("button");
            button.addEventListener("click", function(event) {
                event.preventDefault();
                if (textarea.value.trim() !== '') {
                    textarea.value += "\n";
                }
                textarea.value += string;
                document.querySelector('#send_message_form').submit();
            });
            button.style.padding = ".25rem .5rem"
            responsesDiv.appendChild(button);
        });






        // Get the href attribute of the first message
        var messageLink = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[1]/a', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);

        // Check if the element exists
        if (messageLink && messageLink.singleNodeValue) {
            var messageUrl = messageLink.singleNodeValue.href;
            fetchAndExtract(messageUrl);
        } else {
            console.log('Message link not found.');
        }

        // Remove class "bottom" from specified element
        var bottomElement = document.evaluate('//*[@id="list_messages_my_conversation_messages_items"]/div/div[3]/form/div', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        if (bottomElement && bottomElement.singleNodeValue) {
            bottomElement.singleNodeValue.style.marginTop = "1em";
            bottomElement.singleNodeValue.style.marginBottom = "1em";
            bottomElement.singleNodeValue.classList.remove("bottom");
        } else {
            console.log('Bottom element not found.');
            setTimeout(function() {
                var gen_joined_text = document.getElementById('gen_joined_text');
                gen_joined_text.innerHTML = "<br>" + gen_joined_text.innerHTML;
                // gen_joined_text.style.marginTop = "1em";

                // gen_joined_text.classList.add("custom-margin-top");
            }, 200); // Adjust the delay time as needed


        }






    }else if(window.location.href !== "https://www.camwhores.tv/my/videos/") {
        // Set to store unique video elements
        const processedVideos = new Set();

        function addPrivateVideos() {
            const private_videos = [];

            const videoElements = document.querySelectorAll('.line-premium, .line-private');

            videoElements.forEach(video => {
                const parentDiv = video.parentElement;
                if (
                    parentDiv.tagName === 'DIV' &&
                    parentDiv.parentElement.tagName === 'A' &&
                    !processedVideos.has(parentDiv.parentElement)
                ) {
                    private_videos.push(parentDiv.parentElement);
                    processedVideos.add(parentDiv.parentElement);
                }
            });

            return private_videos;
        }

        async function checkVideoPage(url) {
            try {
                const response = await fetch(url);
                // Check if the response status code indicates an error
                if (!response.ok) {
                    console.error('Error loading video page:', response.status);
                    return true; // Return true if there's an error loading the page
                }

                const html = await response.text();
                const parser = new DOMParser();
                const doc = parser.parseFromString(html, 'text/html');
                const hasElement1 = doc.querySelector('body > div.container > div.content > div.block-video > div.video-holder > div.player > div > div > span') !== null;
                //                                     basically the "This video is a private video uploaded by" message
                const hasElement2 = doc.querySelector('body > div.container > div.content > div.block-album > div.album-holder > div.images > span.message') !== null;
                return hasElement1 || hasElement2;
            } catch (error) {
                console.error('Error checking video page:', error);
                return false;
            }
        }

        async function applyStyleToPrivateVideos() {
            const privateVideos = addPrivateVideos();
            for (const video of privateVideos) {
                const videoLink = video.getAttribute('href');
                // console.log(videoLink);
                const hasElement = await checkVideoPage(videoLink);
                // console.log(videoLink + " " + hasElement);
                if (!hasElement) {
                    video.style.outline = 'green solid 2px';
                    const linePrivate = video.querySelector('div > .line-private');
                    if (linePrivate) {
                        linePrivate.style.display = 'none';
                    }
                    const imgElement = video.querySelector('div > img');
                    if (imgElement) {
                        imgElement.style.opacity = '1';
                    }
                }else{
                    // add ❌
                    const linePrivate = video.querySelector('div > .line-private > span');
                    if (linePrivate) {
                        linePrivate.textContent += ' ❌';

                    }
                }
                await new Promise(resolve => setTimeout(resolve, 25)); // avoid 503
            }
        }
        applyStyleToPrivateVideos();

        function findRelevantKeywords() {
            const titles = document.querySelectorAll('.title');
            titles.forEach(title => {
                const originalText = title.innerHTML;
                highlight_keywords.forEach(keyword => {
                    const regex = new RegExp(keyword, 'gi');
                    if (originalText.match(regex)) {
                        const highlightedText = originalText.replace(regex, '<span style="color: green;">$&</span>');
                        title.innerHTML = highlightedText;
                    }
                });
            });
        }
        findRelevantKeywords()



// Define a global array to store blacklisted image sources
const blacklist = [];

function moveToSecondThumbnail() {
    $('.thumb.lazy-load').off('mouseover').off('mouseout');

    document.querySelectorAll('.thumb.lazy-load').forEach(image => {
        const src = image.getAttribute('src');
        if (blacklist.includes(src)) {
            return;
        }
        const newSrc = src.replace('1.jpg', '2.jpg');
        // console.log("ye")
        if (src && src.endsWith('1.jpg')) {
            image.setAttribute('src', newSrc);
        }

        const images = ['3.jpg', '4.jpg', '5.jpg', '1.jpg', '2.jpg'];
        let currentIndex = 0;
        let intervalId;

        const loopImages = () => {
          if (src && src.endsWith('jpg')) {
            const newSrcName = images[currentIndex];
            const newSrc = src.substring(0, src.length - 5) + newSrcName;
            console.log(newSrc)
            image.setAttribute('src', newSrc);
            currentIndex = (currentIndex + 1) % images.length;
          }
        };

        const mouseoverHandler = () => {
            clearInterval(intervalId);
            intervalId = setInterval(loopImages, 500);
        };


        const mouseoutHandler = () => {
            if (src && src.endsWith('1.jpg') && !(blacklist.includes(src))) {
                image.setAttribute('src', newSrc);
            }
          clearInterval(intervalId);
        };

        // Create a new image element to check if the original image was loaded successfully
        const testImage = new Image();
        testImage.src = src;

        testImage.onload = function() {
            // Image loaded successfully
            // console.log('Image loaded successfully:', src);
        };

        testImage.onerror = function() {
            // Image failed to load (404 error)
            // console.log('Image failed to load (404 error):', src);
            blacklist.push(src);
            image.setAttribute('src', src);

            // Remove previous mouseover and mouseout event listeners
            image.removeEventListener('mouseover', mouseoverHandler);
            image.removeEventListener('mouseout', mouseoutHandler);
        };



        // Add mouseover and mouseout event listeners
        image.addEventListener('mouseover', mouseoverHandler);
        image.addEventListener('mouseout', mouseoutHandler);
    });
    // console.log(blacklist);
}





        altThumbs && moveToSecondThumbnail();

        setInterval(() => {
            applyStyleToPrivateVideos();
            findRelevantKeywords()
            altThumbs && moveToSecondThumbnail();
        }, 750); // Interval in milliseconds (every second)



        if (window.location.href.startsWith("https://www.camwhores.tv/members/")) {
            console.log("NOT messages, user PROFILE");

          function updateH2Element() {
                const h2Element = document.querySelector('#list_videos_uploaded_videos .headline h2');

                if (h2Element) {
                    const text = h2Element.textContent;
                    const startIndex = text.indexOf('(');
                    const endIndex = text.indexOf(')', startIndex);

                    if (startIndex !== -1 && endIndex !== -1 && text.includes("Page")) {
                        const videos_total = parseInt(text.substring(startIndex + 1, endIndex));
                        const rounded_videos_total = Math.ceil(videos_total / 5);
                        const innerHTML = h2Element.innerHTML.trim();
                        if (!innerHTML.includes('/')) {
                            h2Element.innerHTML = innerHTML + '/' + rounded_videos_total;
                        }
                    }
                }
            }

            function addButtonEventListener() {
                console.log("Adding event listener to buttons");
                document.addEventListener('click', function(event) {
                    var target = event.target;
                    if (target && target.matches('a[data-action="ajax"]')) {
                        // console.log("Button clicked");

                        const h2Element = document.querySelector('#list_videos_uploaded_videos .headline h2');
                        const initialText = h2Element.textContent.trim();
                        // console.log("Initial text: " + initialText);
                        const checkChangeInterval = setInterval(function() {
                            const h2Element = document.querySelector('#list_videos_uploaded_videos .headline h2');
                            const currentText = h2Element.textContent.trim();
                            // console.log("Current text: " + currentText);
                            if (currentText !== initialText) {
                                clearInterval(checkChangeInterval);
                                updateH2Element();
                            }
                        }, 100);
                    }
                });
            }


            updateH2Element()
            addButtonEventListener()

      // console.log(friend_request_text)

      if (window.location.href.endsWith("#friends") && !window.location.href.includes("add_to_friends_done")) {
          let addButton = document.querySelector('a[href="#friends"][data-action="add_to_friends"]');
          let textarea = document.getElementById('add_to_friends_message');
          let lastCumTitle = localStorage.getItem('last_cum_title');
          let lastCumUsername = localStorage.getItem('last_cum_username_fr');
          let pageTitle = document.title;
          let username = pageTitle.replace("'s Page", "");
          if (textarea !== null && !addButton.classList.contains('done') && username !== lastCumUsername && lastCumTitle !== null && addButton !== null) {
              textarea.value = "";
              textarea.value += friend_request_text + " " + lastCumTitle;
              console.log("Textarea text set");
              document.querySelector('input[type="submit"].submit[value="Invite"]').click();
              localStorage.setItem('last_cum_username_fr', username);
              addButton.click();
          }
      }else if(window.location.href.includes("add_to_friends_done")){
          let addButton = document.querySelector('a[href="#friends"][data-action="add_to_friends"]');
          if (addButton !== null && !addButton.classList.contains('done')) {
                  addButton.classList.add('done');
              }
      }


  } // END of member profile


        if(window.location.href.startsWith("https://www.camwhores.tv/videos/")){
            const element1 = document.querySelector('body > div.container > div.content > div.block-video > div.video-holder > div.player > div > div > span');
            const element2 = document.querySelector('body > div.container > div.content > div.block-album > div.album-holder > div.images > span.message');

            if (element1 !== null || element2 !== null) {
                const href = document.querySelector('#tab_video_info > div > div.block-user > div > a').href;

                fetch(href)
                    .then(response => response.text())
                    .then(html => {
                    const htmlDoc = new DOMParser().parseFromString(html, 'text/html');
                    const infoMessage = htmlDoc.querySelector('.info-message');
                    if (infoMessage && infoMessage.textContent.includes("is in your friends list.")) {
                        const friends_string = "You're already friends! Reloading in 4 seconds";
                        (element1 || element2).textContent = friends_string;
                        setInterval(() => {
                            location.reload();
                        }, 4000);
                    } else {
                        var infoElement = null;
                        if(element1 !== null){
                          infoElement = element1
                        }else{
                          infoElement = element2
                        }
                        console.log("Not friends!");
                        let headline = document.querySelector('body > div.container > div.content > div.headline > h1');
                        if (headline !== null) {
                            let title = headline.textContent.trim();
                            localStorage.setItem('last_cum_title', title);
                            console.log("Title saved to local storage: " + title);
                            const userProfileUrl = infoElement.querySelector('a').getAttribute('href') + "#friends";
                            console.log(userProfileUrl)
                            const toggleButton = document.createElement('a');
                            toggleButton.classList.add("toggle-button");
                            toggleButton.textContent = "Send request";
                            toggleButton.href = userProfileUrl;
                            toggleButton.style.display= "inline-block";
                            infoElement.appendChild(document.createElement('br'));
                            infoElement.appendChild(toggleButton);
                        } else {
                            console.log("Element not found");
                        }


                    }
                })
                    .catch(error => console.error('Error fetching:', error));
            }
        }

    }
})();