tinyjacky / Rightmove Detail Enhanced

// ==UserScript==
// @name         Rightmove Detail Enhanced
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Extra property information
// @author       Jacky Cheng
// @match        https://www.rightmove.co.uk/properties/*
// @icon         https://www.google.com/s2/favicons?domain=rightmove.co.uk
// @license      MIT
// @require      http://code.jquery.com/jquery-latest.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.core.js
// @connect      localhost
// @connect      bestmove.loophole.site
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @resource     MATERIAL_ICONS https://fonts.googleapis.com/icon?family=Material+Icons

// ==/UserScript==

/* globals jQuery, $, waitForKeyElements, _ */

const loadScores = function(lat, lng) {
    const coordinatePair = `${lat},${lng}`
    const scoreParams = {
      coordinate_pairs: [coordinatePair],
      expand: ['groceries'],
    };

    GM_xmlhttpRequest({
      method: 'GET',
      url: `http://bestmove.loophole.site/scores?${$.param(scoreParams)}`,
      responseType: 'json',
      onload: function(res) {
         const propertyScore = res.response[`${lat},${lng}`];

         const groceryListView = _.compact(propertyScore.scores?.groceries).map((grocery) => {
           return `
             <div class="grocery-item">
               <span class="material-icons">shopping_cart</span>
               <a href="https://www.google.com/maps/dir/${coordinatePair}/${grocery.latitude},${grocery.longitude}/data=!4m2!4m1!3e2" target="_blank">
                 <span class="score-text">${grocery.store_name} (${grocery.postcode}, ${grocery.size_band})</span>
               </a>
             </div>`;
         }).join('');

         $(`
                <div class="score-section">
                  <div class="imd-list">
                    <span class="material-icons">paid</span><span class="score-text">${propertyScore.scores?.income_score?.toFixed(1)}</span>
                    <span class="material-icons">work</span><span class="score-text">${propertyScore.scores?.employment_score?.toFixed(1)}</span>
                    <span class="material-icons">school</span><span class="score-text">${propertyScore.scores?.skill_score?.toFixed(1)}</span>
                    <span class="material-icons">security</span><span class="score-text">${propertyScore.scores?.crime_score?.toFixed(1)}</span>
                    <span class="material-icons">apartment</span><span class="score-text">${propertyScore.scores?.housing_barrier_score?.toFixed(1)}</span>
                    <span class="material-icons">park</span><span class="score-text">${propertyScore.scores?.environment_score?.toFixed(1)}</span>
                    IMD<span class="score-text">${propertyScore.scores?.imd_score?.toFixed(1)}</span>
                  </div>
                  <div class="grocery-list">${groceryListView}</div>
                  <a href="https://www.google.com/maps/dir/${coordinatePair}/birmingham+new+street+station/data=!4m2!4m1!3e3" target="_blank">
                    <span class="material-icons">directions_bus_filled</span><span class="score-text">${propertyScore.scores?.distance_to_town_center?.toFixed(1)}</span>
                  </a>
                  <a href="https://www.google.com/maps/search/${coordinatePair}" target="_blank"><span class="material-icons">map</span><span class="score-text">${propertyScore.postcode}</span></a>
                  <a href="https://epc.opendatacommunities.org/domestic/search?postcode=${propertyScore.postcode}" target="_blank"><span class="material-icons">bolt</span><span class="score-text">Cert</span></a>
                  <a href="https://www.streetcheck.co.uk/postcode/${propertyScore.postcode.split(' ').join('')}" target="_blank"><span class="material-icons">groups</span><span class="score-text" style="margin-left: 5px;">Streetcheck</span></a>
                </div>
         `).insertBefore(
           $('a[href*="#/map"]').first().parent().parent()
         );
      }
    });
};

(function() {
    'use strict';

    GM_addStyle(GM_getResourceText("MATERIAL_ICONS"));
    GM_addStyle(
      `
        .score-section .material-icons {
          font-size: 18px;
        }

        .score-section .score-text {
          vertical-align: top;
          margin-right: 5px;
        }

        .score-section a {
          color: inherit;
        }
      `
    );

    $(document).ready(function() {
        var mapHref = $('a[href*="#/map"]').first().find('img').attr('src');
        var mapParams = new URLSearchParams(mapHref);
        var lat = mapParams.get('latitude');
        var lng = mapParams.get('longitude');
        loadScores(lat, lng);
    });
})();