WME RTC Manager

Utility to manage RTC

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name           WME RTC Manager
// @description    Utility to manage RTC
// @namespace      [email protected]
// @grant          none
// @grant          GM_info
// @version        0.0.2
// @include 	     /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/
// @exclude        https://www.waze.com/user/*editor/*
// @exclude        https://www.waze.com/*/user/*editor/*
// @author         GyllieGyllie
// @license        MIT/BSD/X11
// @require        https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// ==/UserScript==
/* Changelog

*/
/* global W */
/* global I18n */
/* global $ */

const ScriptName = GM_info.script.name;
const ScriptVersion = GM_info.script.version;

let ChangeLog = "RTC Manager has been updated to " + ScriptVersion + "<br />";
ChangeLog = ChangeLog + "<br /><b>New: </b>";
ChangeLog = ChangeLog + "<br />" + "- (0.0.1) Ability to select all linked segments with a matching closure";
ChangeLog = ChangeLog + "<br /><b>Updated: </b>";
ChangeLog = ChangeLog + "<br />" + "- (0.0.2) Fix not all segments being selected in some scenarios";

let wmeSDK;
const options = loadOptions();

// Now validate the options are ok
validateOptions(options);

function log(message) {
  if (typeof message === 'string') {
    console.log('RTC Manager: ' + message);
  } else {
    console.log('RTC Manager: ', message);
  }
}

// the sdk init function will be available after the WME is initialized
function WMERTCManager_bootstrap() {
  if (!document.getElementById('edit-panel') || !wmeSDK.DataModel.Countries.getTopCountry() || !WazeWrap.Ready) {
    setTimeout(WMERTCManager_bootstrap, 250);
    return;
  }

  if (wmeSDK.State.isReady) {
    WMERTCManager_init();
  } else {
    wmeSDK.Events.once({ eventName: "wme-ready" }).then(WMERTCManager_init);
  }
}

function WMERTCManager_init() {
  log("Start");

  // check for changes in the edit-panel
  const speedLimitsObserver = new MutationObserver((mutations) => {
    mutations.forEach(function(mutation) {
      // Mutation is a NodeList and doesn't support forEach like an array
      for (let i = 0; i < mutation.addedNodes.length; i++) {
        const addedNode = mutation.addedNodes[i];

        // Only fire up if it's a node
        if (addedNode.nodeType === Node.ELEMENT_NODE) {
          if (addedNode.querySelector('div.closures')) {
            makeListButtons();
          }
        }
      }

      makeDetailsButtons();
    });
  });

  speedLimitsObserver.observe(document.getElementById('edit-panel'), { childList: true, subtree: true });

  // Catch permalinks
  //makeSigns();

  constructSettings();
  displayChangelog();

  log("Done");

}

// Check if unsafeWindow is availabe, if so use that
('unsafeWindow' in window ? window.unsafeWindow : window).SDK_INITIALIZED.then(() => {
  // initialize the sdk with your script id and script name
  wmeSDK = getWmeSdk({scriptId: "wme-rtc-manager", scriptName: "RTC Manager"});
  WMERTCManager_bootstrap();
});

function displayChangelog() {
  if (!WazeWrap.Interface) {
    setTimeout(displayChangelog, 1000);
    return;
  }

  // Alert the user version updates
  if (options.lastAnnouncedVersion === ScriptVersion) {
    log('Version: ' + ScriptVersion);
  } else {
    WazeWrap.Interface.ShowScriptUpdate(ScriptName, ScriptVersion, ChangeLog + "<br /><br />", "https://github.com/wazers/rtc-manager");

    const updateName = "#wmertcmanager" + ScriptVersion.replaceAll(".", "");
    $(updateName + " .WWSUFooter a").text("Github")

    options.lastAnnouncedVersion = ScriptVersion;
    saveOptions(options);
  }
}

function makeListButtons() {

  const container = $('div.closures-list');

  /*const selectAllButton = $('<wz-button size="sm" style="width: 100%; margin-top: 10px;">Select all</wz-button>');
  selectAllButton.on('click', selectAll);
  container.append(selectAllButton);*/

  /*const saveButton = $('<wz-button size="sm" style="width: 100%; margin-top: 10px;">Delete all</wz-button>');
  saveButton.on('click', deleteAll);
  container.append(saveButton);*/

}

function makeDetailsButtons() {

  const container = $('div.closure');

  if (!container) {
    return;
  }

  const footer = $('div.closure div.action-buttons');

  if ($("#rtcm-detail-all").length > 0) {
    return;
  }

  const selectAllButton = $('<wz-button id="rtcm-detail-all" size="sm"">Select all</wz-button>');
  selectAllButton.on('click', selectAll);
  footer.append(selectAllButton);
}

function selectAll() {

  const ids = [];
  const footerIds = $('div[class^="closureFooterFragmentContainer"] > div > li');
  footerIds.each((el) => ids.push($(footerIds[el]).text()));

  if (ids.length === 0) return;

  const nearbyClosures = wmeSDK.DataModel.RoadClosures.getAll();

  let closure = nearbyClosures.find(closure => ids.indexOf(closure.id) >= 0);

  const segmentIds = [];
  const scanned = new Set();
  if (closure) {
    const segment = wmeSDK.DataModel.Segments.getById({ segmentId: closure.segmentId });

    // Segment not found
    if (!segment) {
      return;
    }

    appendSegments(scanned, segmentIds, segment, closure);
  }

  wmeSDK.Editing.setSelection({
    selection: {
      ids: segmentIds,
      objectType: 'segment'
    }
  });
}

function deleteAll() {

  const selection = wmeSDK.Editing.getSelection();

  if ("segment" !== selection.objectType) {
    return;
  }

  const nearbyClosures = wmeSDK.DataModel.RoadClosures.getAll();

  console.log(selection);
  for (let segmentId of selection.ids) {
    console.log(segmentId);

    const segment = wmeSDK.DataModel.Segments.getById({ segmentId: segmentId });
    console.log(segment);

    if (!segment.hasClosures) {
      continue;
    }
  }


}

function appendSegments(scanned, segmentIds, segment, originalClosure) {

  // This was already scanned
  if (scanned.has(segment.id)) {
    return;
  }

  scanned.add(segment.id);
  const closures = wmeSDK.DataModel.RoadClosures.getAll().filter(rc => rc.segmentId === segment.id);

  // See if any closure matches
  for (let closure of closures) {
    if (originalClosure.description === closure.description
      && originalClosure.startDate === closure.startDate
      && originalClosure.endDate === closure.endDate
      && originalClosure.trafficEventId === closure.trafficEventId) {

      segmentIds.push(segment.id);
      break;
    }
  }

  let linkedSegments = wmeSDK.DataModel.Segments.getConnectedSegments({ segmentId: segment.id });

  for (let ls of linkedSegments) {
    appendSegments(scanned, segmentIds, ls, originalClosure);
  }

  linkedSegments = wmeSDK.DataModel.Segments.getConnectedSegments({ segmentId: segment.id, reverseDirection: true });

  for (let ls of linkedSegments) {
    appendSegments(scanned, segmentIds, ls, originalClosure);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
////
//// Option Logic
////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
function constructSettings() {

  // -- Set up the tab for the script
  wmeSDK.Sidebar.registerScriptTab().then(({ tabLabel, tabPane }) => {
    tabLabel.innerText = 'RTC Manager';
    tabLabel.title = 'RTC Manager Settings';

    tabPane.innerHTML = '<div id="rtc-manager-settings"></div>';

    const scriptContentPane = $('#rtc-manager-settings');

    scriptContentPane.append(`<h2 style="margin-top: 0;">RTC Manager</h2>`);
    scriptContentPane.append(`<span>Current Version: <b>${ScriptVersion}</b></span>`);

    //addTextNumberSettings(scriptContentPane, '', 'Icon Scale in %', 'iconScale');
    //addBooleanSettingsCallback(scriptContentPane, '', 'Enable Clear Sign', 'clearSign', toggleBoolean);
  });

}

function getDefaultOptions() {
  return {
    lastAnnouncedVersion: '',
  }
}

function loadOptions() {
  let text = localStorage.getItem("RTC-Manager-Options");
  let options;

  if (text) {
    options = JSON.parse(text);
  } else {
    options = getDefaultOptions();
  }

  return options;
}

function validateOptions(options) {
  const defaultOptions = getDefaultOptions();

  // Add missing options
  for (let key in defaultOptions) {
    if (!(key in options)) {
      options[key] = defaultOptions[key]
    }
  }
}

function saveOptions(options) {
  const optionsJson = JSON.stringify(options);
  localStorage.setItem("RTC-Manager-Options", optionsJson);
}

function changeText(event) {
  options[event.target.id] = event.target.value;
  saveOptions(options);
}

function addTextNumberSettings(container, title, label, name, step = 1) {
  const currentValue = options[name];

  const textInput = $('<wz-text-input type="number" min="0" max="999" step="' + step + '" id="' + name + '" value="' + currentValue + '"></wz-text-input>');
  const optionHtml = $('<div style="margin-top: 10px;"><span Title="' + title + '">' + label + '</span></div>').append(textInput);

  container.append(optionHtml);

  textInput.on('change', changeText);
}

function addBooleanSettingsCallback(container, title, label, name, clickHandler) {
  const currentValue = options[name];

  const checkbox = $('<wz-checkbox id="' + name + '" Title="' + title + '" name="types" disabled="false" checked="' + currentValue + '">' + label + '</wz-checkbox>');
  const optionHtml = $('<div class="urcom-option"></div>').append(checkbox);

  container.append(optionHtml);

  checkbox.on('click', clickHandler);
}

function toggleBoolean(event) {
  options[event.target.id] = event.target.checked;
  saveOptions(options);
}