Jump to content
  • Participated Threads Tracker (Jcink)

       (0 reviews)

    This will automatically show all the threads that you have participated in (with a single account), and show you who posted last and whether it's your turn. Note that it will only show threads that the person viewing the list is allowed to see, so you can safely use this tracker to track faction threads in a public ooc area, for example. The person looking at the tracker also needs permission to use the site search, so e.g. if guest searching is turned off the tracker will not show anything if you are logged out.

     

    On the jcink default theme, or skins based on it, this requires NO configuration if you post it from the account you want tracked. However, there are settings for your character/site are all in the first <script></script> block, to configure the way it works or adjust it to work on a specific site/skin - you may need to edit those but you shouldn't need to touch anything else (if you're comfortable with css you can fiddle with those bits). You can post this tracker multiple times in the same thread with different characters. Feel free to PM me if you can't get it working on your site.

     

    This uses the skin's default link and text colours, so it works on both light and dark themes. It will adjust to any screen width, and will work in jcink's default mobile mode as well (though it won't show the thread descriptions there).

     

    Settings:

     

    Character Name - if you are posting the tracker from an ooc account, put in the account name of the character you want to track. If you leave this blank, it will track the threads posted by the post author. Depending on your site theme, though, you may need to specify this regardless.

     

    Previous Poster - if your site does strict posting order, you can use the Thread ID (eg if the url of the thread includes showtopic=73 or t=73 then the Thread ID is 73) and the name of the character who posts before you; the tracker will only show that it is your turn if the last poster in that thread is the one who specified here. If you leave this commented out, or for any threads not in this list, the tracker will show it is your turn any time you are not the last poster.

     

    Ignore Forums - you can use this to remove threads in ooc forums from the tracker, if you wish.

     

    Locked Thread Definition - this may need to be changed if the skin has has changed the locked thread icon/macro. If the tracker isn't properly sorting threads into the open/closed section, do any search on your site that you know will turn up at least one locked thread (make sure to show results as threads not as posts). Then, right-click on the locked thread icon/indicator, and hit Inspect Element. You are looking for what type of tag it is, and one unique attribute that will distinguish it from other thread status icons.

     

    Here's the default jcink template:

    95668098_ScreenShot2019-09-25at3_48_28PM.jpg.d992a18c5571f6044b133e6bcf02fd04.jpg

    The lock icon is an <img> tag with a pretty unique title="Closed", so the default setting is:  Locked_Thread_Definition = "img[title=Closed]";

    We could just as easily use the alt text instead: Locked_Thread_Definition = "img[alt=Closed]";
    If there were no thing else usable, we could also also use the src attribute.

     

    Here's a theme that uses fontawesome icons:

    1900934438_ScreenShot2019-09-25at3_27_09PM.jpg.aae90b9042ef0b48ef028fffdf5e0e64.jpg

    The lock icon is an <i> tag with class="fas fa-lock", so we change the setting to: Locked_Thread_Definition = "i[class='fas fa-lock']"; (there's a space, so we have to put it inside single quotes.)

    Since we're using a class name, we can also use a plain css selector: Locked_Thread_Definition = "i.fa-lock";

     

    Next Tracker Delay - avoids search flood control when using this multiple  times in the same thread. This sets the delay in seconds for the second tracker to run the search, the third tracker will wait twice this number from the time the page loads, etc. If you get a flood control error, it should hopefully tell you how long you need to wait between searches, or you can just play around with it until it works.

     


    Actual Template Responsive

    Tracker Code by FizzyElf

    Template code

    <script>
    if (trackernum===undefined) var trackernum = 0;
    else trackernum ++;
    {
    //*** CONFIGURATION ***//
    
    //To specify which character to track, put the account name on the next line
    //if left blank, will default to the posting account.
    const Character_Name = ""; 
    
    //To specify who posts immediately before you when using strict posting order, put them
    //on the next line e.g. {12:"Character Name", 34: "Other Character"}
    const Previous_Poster = {};
    
    //To specify that certain forums should be ignored, put them on the next line, e.g. ["Approved Characters", "Plotting"]
    const Ignore_Forums = [];
    
    //if your skin has changed the icons/macros this might need to be changed
    //const Locked_Thread_Definition = "img[title=Closed]";
    const Locked_Thread_Definition = "i.fa-lock";
    
    //if the icons don't show up, try changing this to false
    const Skin_Already_Uses_Fontawesome = true;
    
    //if you are using multiple of this tracker in the same thread, and you get a flood control error, try increasing this
    const Next_Tracker_Delay = 5;
    
    //*** END OF CONFIGURATION AREA ***//
    
    
    const scriptelements = document.getElementsByTagName("script");
    const Current_Script = scriptelements[scriptelements.length - 1];
    const Is_Mobile = (document.getElementById("mobile") !== null);
    
    function loadJsFile(filename, callback){
        let fileref=document.createElement('script')
        fileref.setAttribute("type","text/javascript")
        fileref.setAttribute("src", filename)
        if (callback) {
           fileref.onreadystatechange = callback;
           fileref.onload = callback;
        }
        document.head.appendChild(fileref);
    }
    
    (Skin_Already_Uses_Fontawesome && !Is_Mobile) || loadJsFile('https://kit.fontawesome.com/fccaf1af24.js');
    
    const startLoadParticipatedTracker = function () {
    const Open_Thread_Wrapper = $("<div class='fizztrackerwrap'></div>");
    const Closed_Thread_Wrapper = $("<div class='fizzhistorywrap'></div>");
    $(Current_Script).before(Open_Thread_Wrapper);
    $(Current_Script).before(Closed_Thread_Wrapper);
    
    let trackedcharacter = Character_Name;
    if (trackedcharacter == "") {
        if (Is_Mobile) trackedcharacter = $(".post-username").last().text().trim();
        else  trackedcharacter = $(".normalname").last().text().trim();
    }
    
    Open_Thread_Wrapper.append(`<p>${trackedcharacter}'s Active Threads</p>`);
    Closed_Thread_Wrapper.append(`<p>${trackedcharacter}'s Closed Threads</p>`);
    
    if (trackedcharacter.trim() == "") {
        Open_Thread_Wrapper.append("<div class='fizzlist-item'>Please specify a character to track.</div>");
        return;
    }
    
    if (Is_Mobile) setTimeout(()=>{FillParticipatedTrackerMobile(trackedcharacter)}, 10 * 1000 * trackernum); 
    else setTimeout(()=>{ FillParticipatedTracker(trackedcharacter)},Next_Tracker_Delay * 1000 * trackernum);
    
    
    
    async function FillParticipatedTracker(username) {
        const thistracker = $("<div></div>");
        const thishistory = $("<div></div>");
        $(Open_Thread_Wrapper).append(thistracker);
        $(Closed_Thread_Wrapper).append(thishistory);
    
        let href = `/index.php?act=Search&q=&f=&u=${username.replace(' ', '%20')}&rt=topics`;
        let data = '';
        try {
            console.log(`fetching ${href}`);
            data = await $.get(href);
            console.log('success.');
        } catch (err) {
            console.log(`Ajax error loading page: ${href} - ${err.status} ${err.statusText}`);
            thistracker.append('<div class="fizztracker-item">Search Failed</div>');
            return;
        }
        let doc = new DOMParser().parseFromString(data, 'text/html');
        
        let meta = $('meta[http-equiv="refresh"]', doc);
        if (meta.length) {
          href = meta.attr('content').substr(meta.attr('content').indexOf('=') + 1);
          try {
            console.log(`fetching ${href}`);
            data = await $.get(href);
            console.log('success.');
          } catch (err) {
            console.log(`Ajax error loading page: ${href} - ${err.status} ${err.statusText}`);
            thistracker.append('<div class="fizztracker-item">Search Failed</div>');
            return;
          }
    
          doc = new DOMParser().parseFromString(data, 'text/html');
        } else {       
           let boardmessage = $('#board-message .tablefill .postcolor', doc).text();
              thistracker.append(`<div class="fizztracker-item">${boardmessage}</div>`);
    
              return;
        }
    
        $('#search-topics .tablebasic > tbody > tr', doc).each(function (i, e) {
            if (i > 0) {
                let cells = $(e).children('td');
                const location = $(cells[3]).text();
                if (!Ignore_Forums.includes(location)) {
                    const locked = (!$(cells[0]).find(Locked_Thread_Definition).length == 0);
                    const title = $(cells[2]).find('td:nth-child(2) > a').text();
                    const threadDesc = $(cells[2]).find('.desc').text();
                    const location = $(cells[3]).text();
                  
                    const href = $(cells[7]).children('a').attr('href');
                    const threadID = href.match(/showtopic=([^&]+)&?/)[1];
                    const lastPoster = $(cells[7]).children('b').text();
                    if (Previous_Poster[threadID]) {
                        var myturn = (lastPoster.includes(Previous_Poster[threadID]))? 'fa-arrow-alt-circle-right':'fa-check';
                    } else {
                        var myturn = (lastPoster.includes(trackedcharacter))? 'fa-check': 'fa-arrow-alt-circle-right';
                    }
    
    
                    let postDate = $(cells[7]).html();
                    postDate = postDate.substr(0, postDate.indexOf('<'));
                    if (postDate.indexOf(",") > 0) {
        	            postDate = postDate.substring(0, postDate.indexOf(",") );
        	        }
                    if (postDate.indexOf(":") > 0) {
        	            postDate = postDate.substring(postDate.indexOf(":") + 1, postDate.length);
        	        }
                    if (locked) {
                        thishistory.append($(`<div class="fizztracker-item"><b><a href="${href}">${title}</a></b><br>
                            ${location} | ${threadDesc}</div>`));
                    } else {
                        thistracker.append($(`<div class="fizztracker-item"><b><span class="status fas ${myturn}"></span><a 
                            href="${href}">${title}</a></b><br>
                            ${location} | ${threadDesc} <br> Last Post: ${lastPoster} - ${postDate}</div>`));
                    }
                }
            }
    
        });
       if (!thistracker.children()) {
            thistracker.append('<div class="fizztracker-item">None</div>');
       }
       if (!thishistory.children()) {
            thishistory.append('<div class="fizztracker-item">None</div>');
       }
    
    }
    
    async function FillParticipatedTrackerMobile(username) {
        const thistracker = $("<div></div>");
        const thishistory = $("<div></div>");
        $(Open_Thread_Wrapper).append(thistracker);
        $(Closed_Thread_Wrapper).append(thishistory);
    
        let href = `/index.php?act=Search&q=&f=&u=${username.replace(' ', '%20')}&rt=topics`;
        let data = '';
        try {
            console.log(`fetching ${href}`);
            data = await $.get(href);
            console.log('success.');
        } catch (err) {
            console.log(`Ajax error loading page: ${href} - ${err.status} ${err.statusText}`);
            thistracker.append('<div class="fizztracker-item">Search Failed</div>');
            return;
        }
        let doc = new DOMParser().parseFromString(data, 'text/html');
        
    
        $('.row4.touch-area', doc).each(function (i, e) {
            if (i > 0) {
                let cells = $(e).children('div');
                const locked = (!$(cells[0]).find(Locked_Thread_Definition).length == 0);
                const title = $(cells[1]).find('b').text();
                const href = $(cells[1]).children('a').attr('href');
                const threadID = href.match(/showtopic=([^&]+)&?/)[1];
                const lastPoster = $(cells[1]).find('span a').text();
                if (Previous_Poster[threadID]) {
                    var myturn = (lastPoster.includes(Previous_Poster[threadID]))? 'fa-arrow-alt-circle-right':'fa-check';
                } else {
                    var myturn = (lastPoster.includes(trackedcharacter))? 'fa-check': 'fa-arrow-alt-circle-right';
                }
    
                let postDate = $(cells[1]).html();
                postDate = postDate.substr(postDate.lastIndexOf('<br>') + 4, postDate.length );
                if (postDate.indexOf(",") > 0) {
        	        postDate = postDate.substring(0, postDate.indexOf(",") );
        	    }
                if (locked) {
                    thishistory.append($(`<div class="fizztracker-item"><b><a href="${href}">${title}</a></b></div>`));
                } else {
                    thistracker.append($(`<div class="fizztracker-item"><b><span class="status fas ${myturn}"></span><a href="${href}">${title}</a></b><br>Last Post: ${lastPoster} - ${postDate}</div>`));
                }
            }
    
        });
       if (!thistracker.children()) {
            thistracker.append('<div class="fizztracker-item">None</div>');
       }
       if (!thishistory.children()) {
            thishistory.append('<div class="fizztracker-item">None</div>');
       }
    
    }
    
    }
    
    if (window.jQuery) startLoadParticipatedTracker();
    else loadJsFile('https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js', startLoadParticipatedTracker);
    
    }
    </script>
    <span style="font-size: 90%;"><i aria-hidden="true" style="color: #fffd;text-shadow: 1px 1px 0 black, -1px -1px 0 black;" class="fas fa-paw"></i> Tracker Code <i aria-hidden="true" style="/*! color: whitesmoke; *//*! text-shadow: 1px 1px 0 black, -1px -1px 0 black; */display: none;" class="fas fa-code-branch"></i> by <a href="http://fizzyelf.jcink.net">FizzyElf </a> <i aria-hidden="true" style="color: #fffd;text-shadow: 1px 1px 0 black, -1px -1px 0 black;" class="fas fa-paw"></i></span>
    <style>
    @import url(https://fonts.googleapis.com/css?family=Arvo);
    .fizztrackerwrap, .fizzhistorywrap { position: relative; max-width: 500px; margin: 10px auto; padding: 1px 15px;}
    .fizztrackerwrap p, .fizzhistorywrap p { position: relative;  font: 15px/1.1 arvo; border-bottom: 1px solid;padding: 0 0.75em;}
    
    .fizzthreadwrap {display: block; position: relative; text-decoration: none;}
    .fizztracker-item .fa-check {color: green;}
    .fizztracker-item .fa-arrow-alt-circle-right {color: brown;}
    .fizztracker-item { margin-left: 2em;}
    .fizztrackerwrap .fizztracker-item { text-indent: -1.5em;}
    .fizztracker-item .status { width: 1.5em; text-align: center;}
    </style>



    User Feedback

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use, Guidelines and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.