Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
Hey @sammich not sure what happened, but looks like this Mod broke for me in Chrome
I have reinstalled TamperMonkey and added the scripts back in but no joy
They are both there, but not running (says no scripts running) even tho one is turned on

Anyone else have this issue with the Mod?
I really really really liked having this, and I am extremely sad that it is broken for me now

Any thoughts to fix it would be appreciated
Edit https://forums.macrumors.com/spy/ to https://forums.macrumors.com/spy/.
 
Whoa. Blast from the past. You two must be the only ones using it.

Happy to have a look later in the day when I get home
 
I lost the (July 2015) changes through which I got this:

2015-07-07-11-34-33-screenshot-png.566856


I'd like to recreate that, but it took a lot of effort (I don't have a head for scripting) … any volunteers? TIA
 
I lost the (July 2015) changes through which I got this:

I'd like to recreate that, but it took a lot of effort (I don't have a head for scripting) … any volunteers? TIA

@grahamperrin, here is a modified version of the script if you are still looking. After copying/installing the script, load up the Spy page and check the box at the bottom of the page to enable Right-aligned mode. It should look close from what I saw in the image. (Tested in Safari 10)

Code:
// ==UserScript==
// @name         Enhanced MacRumors Spy
// @namespace    sd.macrumors.spy
// @version      0.11c
// @author       sammich (original), ShinyDren (small tweaks to the right-align mode)
// @match        https://forums.macrumors.com/spy/
// @match        https://forums.macrumors.com/spy/
// ==/UserScript==

/*
   Doco is all at the link here:
   https://gist.github.com/sammich/383a85b301bef328fd87

   Notes:
    - localStorage is assumed
    - CSS3 transitions are assumed (fallback is no animation)
 */

// see the attached gist to see the unminified version
var styl = document.createElement('style');

var fadeInTimeMs = 300;
styl.textContent =
    '#spyContents .location .major {font-size: smaller;}' +
    '.mod_extras span, .mod_extras label {color: rgb(115, 126, 136);font-size: 12px;margin-left: 6px;}' +
    '.itemWrapper.firstBatch {visibility: hidden;opacity: 0;-webkit-transition: opacity '+fadeInTimeMs+'ms ease-out;-moz-transition: opacity '+fadeInTimeMs+'ms ease-out;-o-transition: opacity '+fadeInTimeMs+'ms ease-out;transition: opacity '+fadeInTimeMs+'ms ease-out;}.itemWrapper.show {opacity: 1;visibility: visible;}' +
    '.loggedInUserPost {background-color:rgb(242, 250, 237) !important; } .meta {float:right;color: rgb(115, 126, 136);font-size: smaller;}#spyContents{margin:0}.titleBar,.sectionHeaders > *,.sectionHeaders .event,#AjaxProgress,.listBlock.event { display:none !important; }.discussionListItem .prefix {position:relative;top:-1px;}.listBlock.info {padding:5px 10px;}.discussionListItem .listBlock {vertical-align:top !important;padding:5px 10px;}@media (max-width: 610px) {.discussionListItem .listBlock {border-right:none;}}.whoWhere{padding-bottom:0;}@media (max-width: 520px) {.discussionList .info > div {padding: 5px 5px 5px 8px !important;}}#ignoreForums textarea {border-radius: 4px;   border: 1px solid rgb(198, 207, 220);padding: 3px;width: 100%;box-sizing: border-box;margin-top: 5px;}#ignoreForums textarea:focus {outline: none;}#ignoreForums span {color: rgb(115, 126, 136);font-size: 12px;margin-left: 6px;}';

document.body.appendChild(styl);

function spyInsert () {
    function modPost(post) {
        var tempEl = $(post);
        var time = tempEl.find('.event .titleText dt').text(),
            event = tempEl.find('.event .titleText h3').text(),
            forum = tempEl.find('.location .major').text(); // grab the post info from the hidden column
        var user = tempEl.find('.location .username').text(); // get the post user so we can highlight the current user's posts
        var ignore = window.spymod_ignoreForums.indexOf(forum) > -1; // set the ignore status

        if (event === 'New Thread') {
            tempEl.find('.info .whoWhere a').prepend('<span class="prefix prefixGreen">+</span> '); // if the post is a new thread, add a tag to the post
        }

        if ( user === window.spymod_username ) {
            tempEl.addClass('loggedInUserPost'); // if it's the user, add a class to highlight it with a faint green
        }

        if (!window.spymod_rightMode) {
            tempEl.find('.location .whoWhere').prepend('<span class="meta">' + time + '</span>'); // add the new tag for the timestamp of the post
        } else { // Right-aligned mode is enabled (on bottom of page).
            tempEl.find('.info .whoWhere').prepend('<span class="meta">' + time + '</span>'); // add the new tag for the timestamp of the post
            var snip = tempEl.find('.listBlock.location');
            tempEl.find('.info').after(snip);

            //--- START Code Group A ---// Comment this section and uncomment Group B section to flip which text is on top and change text sizes.
            //snip = tempEl.find('.listBlock.location .major');
            //tempEl.find('.listBlock.location .whoWhere').prepend(snip);
            //--- END Code Group A ---//

            //--- START Code Group B ---// Comment this section and uncomment Group A section to return which text is on top to original.
            snip = tempEl.find('.listBlock.info .snippet');
            snip.prev().before(snip);
            tempEl.find('.location .major').css({fontWeight: "normal"}); // #spyContents .location .major {font-weight: normal;}
            tempEl.find('.location .whoWhere .username').css({display: "block", textAlign: "right", fontSize: "x-small"}); // .location .whoWhere .username {display: block;text-align: right;font-size: x-small;}
            tempEl.find('.listBlock.location').css("cssText", "vertical-align: middle !important;"); // .discussionListItem .listBlock.location {vertical-align: middle !important;}
            tempEl.find('.info .meta').css({padding: "10px 0 0 5px", fontSize: "x-small"}); // .discussionListItem .info .meta {padding: 10px 0 0 5px;font-size: x-small;}
            tempEl.find('.info .snippet').css({fontStyle: "normal", fontSize: "initial"}); // .discussionListItem .info .snippet {font-style: normal;font-size: initial;}
            tempEl.find('.info .whoWhere a').css({display: "block", textAlign: "right", fontSize: "100%", fontStyle: "italic"}); // .discussionListItem .info .whoWhere a {display: block;text-align: right;font-size: 100%;font-style: italic;}
            //--- END Code Group B ---//
        }
        return ignore ? null : tempEl; // don't return anything if the post isn't to be shown anyway
    }

    // for the intial run, we want to avoid the complex timeout loop prepending multiple posts
    if (!window.spymod_insertHasRunOnce) {
        window.spymod_insertHasRunOnce = true;

        var fragment = spyItems.reverse().map(function (post) {
            post = modPost(post);
            return post ? '<div class="itemWrapper firstBatch" style="display:block">' + post[0].outerHTML + '</div>': '';
        }).join('');

        // add the posts
        $('#spyContents .discussionListItems').html(fragment);

        setTimeout(function () {
            $('#spyContents .discussionListItems').find('.itemWrapper').addClass('show');
        }, 50); // add a delay as there seems to be a judder when you run it too close to page load

        // intialise the posts so that it skips the normal path below
        spyItems = [];
    }

    if (spyItems.length) {
        var post = modPost(spyItems.shift()); // create the fragment so we can inspect and modify it

        // ignored posts will be falsey
        if (post) {
            // modified to use the modified HTML fragment
            $('#spyContents .discussionListItems').prepend('<div class="itemWrapper">' + post[0].outerHTML + '</div>');
            $('#spyContents .itemWrapper:first-child').slideDown(spyTiming / 3);
        }
        if ($('#spyContents .itemWrapper').length > 25) {
            var lastChild = $('#spyContents .itemWrapper:last-child');
            lastChild.slideUp(spyTiming / 2, function() {
                lastChild.remove();
            });
        }
    }

    if (spyItems.length) { // This version does not show a syntax error in tampermonkey (still works the same as the original I think).
        setTimeout(spyInsert, spyTiming);
    } else {
        spyTiming = 2E3;
        setTimeout(getSpyItems, 5E3);
    }
    // spyItems.length ? setTimeout(spyInsert, spyTiming) : (spyTiming = 2E3, setTimeout(getSpyItems, 5E3)); // Original, shows syntax error in tampermonkey but still works.
}

function _runSpyMod() {
    window.spymod_username = $('#header .accountUsername').text();
    window.spyTiming = 0;

    $('.breadBoxBottom').after(

        // ignore forums input
        '<div id="ignoreForums"><span>Ignore Forums (separate with semi-colons):</span><textarea placeholder="Forum 1;Forum 2"></textarea></div>' +

        // right-mode spy
        '<div class="mod_extras"><input type="checkbox" id="spymod_rightmode"><label for="spymod_rightmode">Right-aligned mode (reload page after setting)</label></div>'
    );

    // note that LS returns a string not the bool. Any truthy value is true
    window.spymod_rightMode = !!localStorage.getItem('_mod_rightmode');

    $('#spymod_rightmode')
        .prop('checked', window.spymod_rightMode)
        .change(function () {
        if (this.checked) {
            localStorage.setItem('_mod_rightmode', true);
        } else {
            localStorage.removeItem('_mod_rightmode');
        }
    });

    // ignore setup
    var ignored = localStorage.getItem('_mod_ignoredForums') || '';
    window.spymod_ignoreForums = ignored.split(';');

    $('#ignoreForums textarea')
        .val(window.spymod_ignoreForums.join(';') + ';')
        .on('paste change', function(e) {
        var el = this;

        // skip a beat because the paste event will otherwise give you the value before the paste
        setTimeout(function() {
            var ignore = el.value.split(';');

            // remove any too short values like consecutive semi-colons
            for (var i = 0; i < ignore.length; i++) {
                if (ignore[i].length < 2) {
                    ignore.splice(i--, 1);
                }
            }

            // save
            localStorage.setItem('_mod_ignoredForums', ignore.join(';'));

            // set global
            window.spymod_ignoreForums = ignore;

            // set display
            el.value = window.spymod_ignoreForums.join(';') + ';';

            // update spy
            $('.itemWrapper .location .major').each(function() {
                var el = $(this);

                el.closest('.itemWrapper').toggle(window.spymod_ignoreForums.indexOf(el.text()) < 0); // Seems to work the same way. Removed the exclamation point and switched the comparison operator and value.
                // el.closest('.itemWrapper').toggle(!window.spymod_ignoreForums.indexOf(el.text()) > -1); // Original, syntax warning in tampermonkey.
            });
        });
    });
}

function _runSuperMod() {
    $('body').append('<div id="mainview"><div id="spymod_col1"><div class="header">asdasd</div></div><div id="spymod_col1"><div class="header"><select name="" id="threadselector"></select></div></div><div id="threadbox"><iframe src="" frameborder="0" id="threadframe"></iframe></div></div>');
}

var script = document.createElement('script');
script.textContent = spyInsert.toString() + ';(' + _runSpyMod.toString() + ')()'; // + ';(' + _runSuperMod.toString() + ')()';
document.body.appendChild(script);

If you want to change the css text formatting go to the "Code Group B" section.
 
  • Like
Reactions: grahamperrin
Excellent! Thanks @ShinyDren, that works with https://forums.macrumors.com/spy/

Curiously, URLs such as https://forums.macrumors.com/spy/#content and https://forums.macrumors.com/spy/#spyContents appear to scroll down to at, or near, a content area with no content, but that's not an issue with the script.

There's the old problem of MacRumors not using its own iPhone, iPad, Apple Watch, Apple TV, and iPod area to write about those things so, for example, eighty-seven percent of these discussions are misplaced:

2017-09-23 12:34:49.png

– but that's a site management/editorial issue. We can't script out inconsiderate placement.
 
Hey @sammich just want to thank you again for this
I use it ALL the time
I was setting up a new browser today and came back here for the code

This is the BEST way to use the Spy for me and I love it
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.