WME RTC Manager

Utility to manage RTC

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==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);
}