// ==UserScript==
// @name WME URCom
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAATaSURBVEhLhVZbbJRFFD4ze+l2W1t7oxfqYgRNG6uiNqAmJqjYUCWx0fBgCApKfNAoaKKJicilb8bXPoBoCfES00R4UBMTQknUxJqixZQIbjQUtrgtbaHb7i57+Wc85/wzv9t/m/Ltnp1zzsx3vrnt/itgBejz28IpuPakVqoPtO7WAK1SQKNSMCME/CuFGNVSnqyBptPi3qG8oZVhWRGttwXm/0ju0lofxKht6TCUKqddFULsr72/ZVCIIcfkPJSNzpzb1J5XxZMo8LDtRR9dDChGH3AZNk9AAVcb4GxFINQXfeBMgiMDU8bFjXOPPwRF9Z3SqoViIrOAaf05gsYXT8D4EmQStHz29u4ff+MkwhPJjD26Ol+AUQXaFcAXkSxs7M+XoqQvGQlFu6PrT09SIOmDziCX1yeUwhXQGIVDteLWi/G0y/K0Ov8Y12/JFTInqC5GKI24/svGV3DIp8ThhLc+t07wti4IVnWCDDdBMR2H4sLvoAsz3Gd2jeHn48perXtk5DOhR18LzRXG/sER7ZZFY9ADGWqE6NoPIFz3GJMstHMTspcH4Gbya4rQTFUfH88tURdaf5e48fPGHkc7P9CMqMP7kFGoffArCERWU2JZZK8cRbHD7JfxaR2YkwHokUoVn6MZaAf3k4xmg+/omjdWFCBE2ndCoHIdc/x8wPPReE6qoPskOhvcwzPGB6wg3NQLxdQ4LIzvcSsiVG4aUmO7sGCWYyGCEG58mg66jF8itEHiZ6u9FaRMBBFuw/OoARlpQ7EtXJAggrUQXrUV9yBiMngpqju9W2X51FKOY61bUQRW0Qx4uXY27s3G21QPFc297BNEoAIibS/QgZoMQKDmPuTg96OUjyas76gmqR0n5S3XzMJJJ0AX06bMypDBatyyzUv4JOiuioUXJCjAnwG7PExip1BFvDlfmjK3RiS2Yykf67MotVgft0uPkDJ3kLoRzMQHIH/tJ6pxSwhcjZ/PqyHTakRKJU+5h+buqdsSoQALZ1+HxfMHMVfkYsshO/EFpH7dXc5Hn4Sl0qeEHt4Umc1OJTDXwN8eAgYW5FXdsxeCNR0oeIjFtZOD6q59fG6L4wfcgQQfH8PZhsrmds7Oft+5Tzn6kC1dcnkYxCnl++fCMfp+vpTiw4Zn/uznu1oPd36ETZxYdPXce44Ubum8TI7P7v9+75rSWOPbflSMm7r2lw3E1W/u7ggGxTASmilNsyGehRebWbsflm587kNfiCkZCD/RuHX8AmXcbx2m256P/zV3XfTg+Gnzc4DmHibFClfB997LI8v0sW/6EFOpeWczClykgGBFGB0vX7xweTrfi6QEkeh2WCH2uajZJsx7YqbFiSUmpwtb1r30tydA4CcXghZKJo98Oz9bFQ0c74yFoqEAdCE5RE8Ifq5bIXzzU4N9jrPZnDp8dDi9/cX9k/TIxSSDWypMoBWRT6Ke9e9ort/+VOXeqqh4C+OlIDoyFjLq46EzuYH3jyXnMEN/h0qNRuEvmwsrQi0ZiVhfxgdje2oq5QH7L8XUh7lF/W7n7olP0MX9YqPC1idbIkKtNStIQjYHl46tebuyAvqJhkcP6bx8Z+3OS0eoD2ELerM3OQL5jFIBKh40Fi6xiivHY+8lP79jZmIw9qavL4RG4+1W24kiAP4DWJsUPMbPec8AAAAASUVORK5CYII=
// @namespace https://gitlab.com/WMEScripts
// @version 2025.02.23.01
// @description This script is for replying to user requests the goal is to speed up and simplify the process!
// @match *://*.waze.com/*editor*
// @exclude *://*.waze.com/user/editor*
// @author tunisiano187 based on Rick Zabel '2014, maintained by GyllieGyllie
// @license MIT/BSD/X11
// @compatible chrome firefox
// @connect gitlab.com
// @connect *
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @supportURL mailto:incoming+WMEScripts/[email protected]
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// ==/UserScript==
/* global $, GM_info, GM_xmlhttpRequest, WazeWrap, unsafeWindow, getWmeSdk */
const ScriptName = GM_info.script.name;
const URCommentVersion = GM_info.script.version;//var URCommentVersion = "1.5.4"; //branched from 0.9.3
const URCommentUpdateMessage = "yes"; // yes alert the user, no has a silent update.
/* Changelog
1.9.2 - Sizing Signature field
1.9.3 - Details about the Signature and the refresh need
1.9.4 - Relocate Signature settings
1.9.5 - Auto email errors
1.9.6 - Pictures in pills
1.9.7 - Pills corrections
1.9.8 - Title and pills updates
1.9.9 - Credits et corrections
1.9.10 - Bug closure text correction
1.9.11 - Design and some corrections
1.9.12 - icons before comments in the comments tab
1.9.13 - Don't complete comments, disable textarea and hide send button id the UR is locked (Out of editing area) or closed
1.9.14 - Adding Francais Belgique à la liste
2018.07.18.01 - New versionning numbers to ease the checks for last update
2018.08.04.01 - Adding the NL version
2018.08.08.01 - Signature even if no predefined answer found
2018.08.12.01 - Local version update
2018.08.15.01 - Adding the ability to add Titles in the comments part
2018.08.15.02 - Translator's name
2018.08.15.03 - Removing the open database option for now
2018.08.15.04 - Bad comment break the script
2018.08.15.05 - Title spaces
2018.08.15.06 - Test text moved
2018.08.16.01-03 - Design changes
2018.08.16.04 - Bug correction
2018.08.17.01 - Handling the ending dot on comments title that breaks the autocomplete
2018.08.18.01-03 - Change URCom logo + Design
2018.08.21.01
2018.09.02.01 - undefined mask
2019.05.19.01 - Adapt timeout to avoid useless messages
2019.08.15.01 - Adapt to the new WME version
2019.11.24.01 - Yellow Background if message from the user
2020.01.18.01 - Support of unknown reports
2020.01.18.02 - remove alert
2020.01.13.01 - Solving signature's return problem
2020.02.15.01 - Error version number
2020.04.12.01 - Add user's message in the (..) answer
2020.08.07.01 - Remove the line that hide the textarea
2023.06.04.01 - New design based on current WME styling
2023.06.16.01 - Major code overhaul & bug fixing
2023.06.16.02 - Fix migration logic being broken
2023.06.18.01 - Filter cleanup, small fixes, new features
2023.07.03.01 - Add feature to create custom responses
2023.08.03.01 - Fixes after new WME Update
2023.08.03.02 - Fixes after WME update rollback
2023.08.15.01 - Change how custom list data is stored to fix all browser support
2023.08.16.01 - Small fix to changes from yesterday
2023.08.21.01 - Small fix in migration logic being broken if you use script first time
2024.03.22.01 - Fix auto response no longer working
2024.05.29.01 - Fix some issues after WME update
2025.02.12.01 - Major overhaul, no more separate language scripts & prep for multi language
>>>>>>> URComments(dev).user.js
*/
let URCommentVersionUpdateNotes = "UR Comments has been updated to " + URCommentVersion + "<br />";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "In this update we've done a major update to the script. Since a few months it's no longer possible to load custom translations & repsonses from separate TM Scripts. In this update we have fully redone the system and all previously maintained translations/responses are now default integrated into the main script.";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br /><br />" + "<b>Things that changed:</b>";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- No more need for additional scripts for other languages";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- Filters are now fully removed, as almost all of it is supported by WME filtering";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- Script language & responses are no longer linked, you can use the script in a different language than the responses";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br /><br />" + "<b>Steps to take to use the script again:</b>";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- Remove any old additional script you had installed for your custom language/responses";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- Navigate to the settings of the script and select in which language the script should operate";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- On the text tab, select which default list you want to use";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- That's it, you should now be able to use URCom like before";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br /><br />" + "<b>Any issues/feedback?</b>";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br />" + "- If you found a bug, want another language to be supported or any other suggestions please report them on <a href='https://gitlab.com/WMEScripts/URComments-French/-/issues' target='_blank'>our Gitlab</a>";
URCommentVersionUpdateNotes = URCommentVersionUpdateNotes + "<br /><br />";
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////
////// Define items that need to be at the root level so they can be used inside functions
//////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
let wmeSDK;
let migrate = false;
const options = loadOptions();
// If we need to migrate, do the migration now
if (migrate) {
migrateOptions();
}
// Now validate the options are ok
validateOptions(options);
let DB;
const SupportedLanguages = [
"English",
"Nederlands",
"Français",
];
const defaultLists = new Map([
["English", "URComDefault"],
["Nederlands", "Nederlands"],
["Francais Belgique", "Francais_Belgique"],
["Luxembourg", "Luxembourg"]
])
let CustomLists = [];
let CustomListText = [];
let InitReady = false;
let ShowTextEditFields = false;
let ShowTextOptionButtons = true;
let TextEditIndex = undefined;
let DeleteTextMode = false;
// Array that holds the comments
let URCommentsArray;
// Waze swaps out the close button on the UR window after you click send. we use this to grab the close and compare to the new one
let CloseButtonHolder = "";
// Since we are scanning for open UR I need to keep track of the current urID so the comments can be overridden
let UrCommentLasturID = "";
// This is used to hold the info about the previous tab, before we auto switched tabs
let PreviousTab = null;
let PreviousTabPosition = null;
// Return to zoom instead of zoom 0
let ReturnToCurrentZoom = "";
let translation;
let knownLanguages;
//var UrCommentsIcon = 'data:image/png;base64,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';
const UrCommentsIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAATaSURBVEhLhVZbbJRFFD4ze+l2W1t7oxfqYgRNG6uiNqAmJqjYUCWx0fBgCApKfNAoaKKJicilb8bXPoBoCfES00R4UBMTQknUxJqixZQIbjQUtrgtbaHb7i57+Wc85/wzv9t/m/Ltnp1zzsx3vrnt/itgBejz28IpuPakVqoPtO7WAK1SQKNSMCME/CuFGNVSnqyBptPi3qG8oZVhWRGttwXm/0ju0lofxKht6TCUKqddFULsr72/ZVCIIcfkPJSNzpzb1J5XxZMo8LDtRR9dDChGH3AZNk9AAVcb4GxFINQXfeBMgiMDU8bFjXOPPwRF9Z3SqoViIrOAaf05gsYXT8D4EmQStHz29u4ff+MkwhPJjD26Ol+AUQXaFcAXkSxs7M+XoqQvGQlFu6PrT09SIOmDziCX1yeUwhXQGIVDteLWi/G0y/K0Ov8Y12/JFTInqC5GKI24/svGV3DIp8ThhLc+t07wti4IVnWCDDdBMR2H4sLvoAsz3Gd2jeHn48perXtk5DOhR18LzRXG/sER7ZZFY9ADGWqE6NoPIFz3GJMstHMTspcH4Gbya4rQTFUfH88tURdaf5e48fPGHkc7P9CMqMP7kFGoffArCERWU2JZZK8cRbHD7JfxaR2YkwHokUoVn6MZaAf3k4xmg+/omjdWFCBE2ndCoHIdc/x8wPPReE6qoPskOhvcwzPGB6wg3NQLxdQ4LIzvcSsiVG4aUmO7sGCWYyGCEG58mg66jF8itEHiZ6u9FaRMBBFuw/OoARlpQ7EtXJAggrUQXrUV9yBiMngpqju9W2X51FKOY61bUQRW0Qx4uXY27s3G21QPFc297BNEoAIibS/QgZoMQKDmPuTg96OUjyas76gmqR0n5S3XzMJJJ0AX06bMypDBatyyzUv4JOiuioUXJCjAnwG7PExip1BFvDlfmjK3RiS2Yykf67MotVgft0uPkDJ3kLoRzMQHIH/tJ6pxSwhcjZ/PqyHTakRKJU+5h+buqdsSoQALZ1+HxfMHMVfkYsshO/EFpH7dXc5Hn4Sl0qeEHt4Umc1OJTDXwN8eAgYW5FXdsxeCNR0oeIjFtZOD6q59fG6L4wfcgQQfH8PZhsrmds7Oft+5Tzn6kC1dcnkYxCnl++fCMfp+vpTiw4Zn/uznu1oPd36ETZxYdPXce44Ubum8TI7P7v9+75rSWOPbflSMm7r2lw3E1W/u7ggGxTASmilNsyGehRebWbsflm587kNfiCkZCD/RuHX8AmXcbx2m256P/zV3XfTg+Gnzc4DmHibFClfB997LI8v0sW/6EFOpeWczClykgGBFGB0vX7xweTrfi6QEkeh2WCH2uajZJsx7YqbFiSUmpwtb1r30tydA4CcXghZKJo98Oz9bFQ0c74yFoqEAdCE5RE8Ifq5bIXzzU4N9jrPZnDp8dDi9/cX9k/TIxSSDWypMoBWRT6Ke9e9ort/+VOXeqqh4C+OlIDoyFjLq46EzuYH3jyXnMEN/h0qNRuEvmwsrQi0ZiVhfxgdje2oq5QH7L8XUh7lF/W7n7olP0MX9YqPC1idbIkKtNStIQjYHl46tebuyAvqJhkcP6bx8Z+3OS0eoD2ELerM3OQL5jFIBKh40Fi6xiivHY+8lP79jZmIw9qavL4RG4+1W24kiAP4DWJsUPMbPec8AAAAASUVORK5CYII=';
const UrCommentsTextPic = '<img alt="" style="margin-bottom: 1px; height: 12px;" src="data:image/png;base64,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\" />'; // Picture of the number of comments
const UrCommentsTimePic = '<img alt="" style=\"margin-bottom: 1px; height: 12px;" src=\"data:image/png;base64,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\" />'; // Delay picture
const URC_img_waze_editor = '<img alt="" style="height: 15px; margin-right: 5px;" src="data:image/png;base64,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" />';
const MagnifyingIcon = '<img alt="" style="margin-bottom: 1px; height: 12px;" src="data:image/png;base64,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" />';
const RefreshIcon = '<img alt="" style="margin-bottom: 1px; height: 12px;" src="data:image/png;base64,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\n" />';
// Keep references to our html elements
let scriptContentPane;
let nConfirm;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////
////// bootstrap
//////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
async function URComments_init() {
if (!WazeWrap.Ready) {
setTimeout(URComments_init, 250);
return;
}
await initDatabase();
console.log("[URCom] Loading data");
await loadTranslation();
await loadResponses();
const dsRequest = DB
.transaction("data-store")
.objectStore("data-store")
.get("languages");
dsRequest.onsuccess = (event) => {
if (event.target.result?.responses && event.target.result.responses.length > 0) {
const data = event.target.result.responses[0];
console.log(data);
knownLanguages = data.languages;
} else {
knownLanguages = [];
}
};
while (!dataReady()) {
await sleep(100);
}
console.log("[URCom] Data loaded");
const request = DB
.transaction("custom_lists")
.objectStore("custom_lists")
.getAll();
request.onsuccess = (event) => {
if (event.target.result) {
const results = [...event.target.result];
results.sort((a, b) => {
return a.order - b.order
});
CustomLists = [];
defaultLists.forEach((value, key) => {
CustomLists.push("* " + key);
});
results.forEach(list => {
CustomLists.push(list.name);
})
CustomLists.push(translate("list.new"));
loadCustomText(() => {
InitReady = true;
});
}
};
startCode();
displayChangelog();
}
function loadCustomText(callback) {
if (options.CustomTextList) {
if (defaultLists.has(options.CustomTextList)) {
callback();
return;
}
CustomListText = [];
// Verify it still exists
if (CustomLists.indexOf(options.CustomTextList) === -1) {
alert(translate("prompts.list-gone"));
options.CustomTextList = "English";
saveOptions(options);
loadResponses().then(callback);
} else {
console.log("[URCom] Loading custom text: " + options.CustomTextList);
const request = DB
.transaction("custom_lists")
.objectStore("custom_lists")
.get(options.CustomTextList);
request.onsuccess = (event) => {
if (event.target.result) {
const results = [...event.target.result.responses];
for (let i = 0; i < results.length; i++) {
const result = results[i];
CustomListText.push({
sorting: result.sorting,
name: result.name,
text: result.text,
status: result.status,
});
}
CustomListText.sort((a, b) => {
return a.sorting - b.sorting
});
}
callback();
};
}
} else {
callback();
}
}
function displayChangelog() {
if (!WazeWrap.Interface) {
setTimeout(displayChangelog, 1000);
return;
}
if (URCommentUpdateMessage === "yes") {
// Alert the user in URComment version updates
if (localStorage.getItem('URComVersion') === URCommentVersion) {
console.log("[URCom] Version - " + URCommentVersion);
} else {
WazeWrap.Interface.ShowScriptUpdate(ScriptName, URCommentVersion, URCommentVersionUpdateNotes + "<br />", "https://gitlab.com/WMEScripts/URComments-French");
const updateName = "#wmeurcom" + URCommentVersion.replaceAll(".", "");
$(updateName + " .WWSUFooter a").text("Gitlab")
localStorage.setItem('URComVersion', URCommentVersion);
}
}
}
async function refreshUI() {
await loadTranslation();
await loadResponses();
// Clear the html from the tabs
$("#sidepanel-Comments").html('');
// Reload the content
init();
}
async function loadTranslation() {
// Language isn't know so fall back to English
if (!SupportedLanguages.includes(options.Language)) {
options.Language = "English";
saveOptions(options);
}
console.log("[URCom] Selected language: " + options.Language);
let lang = "en";
switch (options.Language) {
case "Nederlands": {
lang = "nl";
break;
}
case "Français": {
lang = "fr";
break;
}
}
await makeHTTPRequest('GET', "https://gitlab.com/WMEScripts/URComments-French/-/raw/master/i18n/" + lang + ".json")
.then((response) => {
translation = response;
console.log("[URCom] " + translate("example"));
})
.catch((error) => {
console.log(error);
})
console.log("[URCom] Language loaded!");
}
async function loadResponses() {
// We are using a custom list
if (!defaultLists.has(options.CustomTextList)) {
return;
}
console.log("[URCom] Selected default list: " + options.CustomTextList);
const fileName = defaultLists.get(options.CustomTextList)
await makeHTTPRequest('GET', "https://gitlab.com/WMEScripts/URComments-French/-/raw/master/presets/" + fileName + ".json")
.then((response) => {
URCommentsArray = response;
console.log("[URCom] Loaded default responses.");
})
.catch((error) => {
console.log(error);
})
console.log("[URCom] Default list loaded!");
}
function dataReady() {
return !!knownLanguages;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////
////// init
//////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
function applyCss() {
// CSS
// Expand the UR textarea so we can verfiy what comment we clicked on. special thanks to SeekingSerenity
let g = '.ur-comment-list .comment-list { bottom: 200px !important; } .ur-comment-list .new-comment-form textarea { height: 140px !important; } .ur-comment-list .new-comment-form { height: 200px !important; }';
const wazeHeight = $('.view-area').height();
if (wazeHeight > 500) {
// beta-editor comment textarea
g = g + ' .new-comment-form .new-comment-text { height: 140px !important; }';
}
// css for making pane fit
g = g + '#sidepanel-Comments { width: 100% !important; }';
// css for items in my tab that are in a label
g = g + '#sidepanel-Comments label { cursor:pointer; margin:0px 0px 0px; vertical-align: middle;font-size: 10px;}';
// css for checkboxes
g = g + ' #sidepanel-Comments .URCommentsCheckbox { text-decoration:none; cursor:pointer; color: #000000; margin:0px 0px 0px; vertical-align: middle; font-size: 12px;}';
// css for our comments,
g = g + ' #sidepanel-Comments .URComments { text-decoration:none; cursor:pointer; color: #000000; font-size: 12px;}'; // margin-top: 5px;
// css for our presets,
g = g + ' #sidepanel-Comments .URCommentsPresets { text-decoration:none; cursor:pointer; color: #000000; font-size: 10px;}';
// css for our nav tabs,
g = g + ' #comments-tab22 ul { font-size: 12px; padding: 0px;}';
// css for our nav tabs links,
g = g + ' #comments-tab22 a { padding: 3px !important ; margin-right: 0px !important;}';
// keep the padding on our nav tabs
g = g + ' #comments-tab22 nav-tabs { padding: 0px !important;}';
// css for non selected UR opacity
g = g + " .olMap.problem-selected .map-problem:not(.selected) { opacity: .5 !important;}";
// css to fix the beta editors UR window
g = g + ' .problem-edit .section .title { line-height: 15px !important; }';
g = g + ' .problem-edit .header { line-height: 15px !important; padding: 0px 15px!important; }';
g = g + ' .problem-edit .section .content { padding: 5px !important;}';
// css to undo some of the changes from maximizer
if ($("#sidebar").width() < 300) {
//g = g + '#sidebar { max-width: 290px !important;}';
g = g + ' .show-sidebar .row-fluid .fluid-fixed {margin-left: 290px !important;}';
}
// move description up a div
g = g + ' .problem-edit .description { background-color: white; overflow-x: hidden; overflow-y: auto; max-height: 80px; border-bottom: 2px solid #e9e9e9;}';
// Make some spacing between checkboxes in settings
g = g + ' .urcom-option { margin-top: 10px; }';
// Our button style
g = g + ' .urcom-button { margin: 5px 0; border: 1px solid rgba(27, 31, 35, 0.15); border-radius: 6px; box-shadow: rgba(27, 31, 35, 0.04) 0 1px 0, rgba(255, 255, 255, 0.25) 0 1px 0 inset; background-color: #FAFBFC; cursor: pointer; font-size: 14px; font-weight: 500; line-height: 20px; list-style: none; padding: 3px 10px; position: relative; transition: background-color 0.2s cubic-bezier(0.3, 0, 0.5, 1); }'
// Append our css to the head
$("head").append($('<style id="URCOM-CSS" type="text/css">' + g + '</style>'));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////
//// Option Methods
////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
function addCommentTexts(container) {
if (!ShowTextEditFields) {
// Custom Text
addDropdownSettings(container, "list.name.tooltip", "list.name.title", 'CustomTextList', CustomLists, changeCustomTextList);
const header = $('<h5 style="margin-top: 20px;">' + translate("list.responses") + '</h5>');
container.append(header);
}
// Start generating the comment list and mouse click handlers
if (options.CustomTextList && !defaultLists.has(options.CustomTextList)) {
if (ShowTextEditFields) {
let headerText;
if (TextEditIndex !== undefined && TextEditIndex !== -1) {
headerText = translate("list.edit");
} else {
headerText = translate("list.response.title.title");
}
// Add options to setup custom text
const header = $('<h5 style="margin-top: 20px;">' + headerText + '</h5>');
container.append(header);
const titleInput = $('<wz-text-input id="customTextTitle"></wz-text-input>');
const titleWrapper = $('<div class="urcom-option"><span Title="' + translate("list.response.title.tooltip") + '">' + translate("list.response.title.title") + '</span></div>').append(titleInput);
container.append(titleWrapper);
const textInput = $('<wz-textarea id="customTextText" style="height: 130px; width: 270px;"></wz-textarea>');
const textWrapper = $('<div class="urcom-option"><span Title="' + translate("list.response.response.tooltip") + '">' + translate("list.response.response.title") + '</span></div>').append(textInput);
container.append(textWrapper);
const selectWrapper = $('<div class="urcom-option" title="' + translate("list.response.status.tooltip") + '"></div>');
selectWrapper.append('<span>' + translate("list.response.status.title") + '</span>');
selectWrapper.append('<br />');
const select = $('<select name="customTextStatus" id="customTextStatus" style="width: 100%;"></select>');
select.append('<option value="open">open</option>');
select.append('<option value="open">closed</option>');
select.append('<option value="open">notidentified</option>');
selectWrapper.append(select);
container.append(selectWrapper);
const saveButton = $('<wz-button size="sm" style="width: 100%; margin-top: 10px;">' + translate("save") + '</wz-button>');
saveButton.on('click', saveCustomText);
container.append(saveButton);
const cancelButton = $('<wz-button size="sm" style="width: 100%; margin-top: 10px;">' + translate("cancel") + '</wz-button>');
cancelButton.on('click', cancelTextEdit);
container.append(cancelButton);
} else {
// Go over the array and generate comment divs
for (let i = 0; i < CustomListText.length; i++) {
const text = CustomListText[i];
let reply = text.text;
addComments(container, i, {
title: text.name,
status: text.status,
response: reply
});
}
if (ShowTextOptionButtons) {
const options = $('<h5 style="margin-top: 20px;">' + translate("list.options") + '</h5>');
container.append(options);
const addItem = $('<div style="width: 100%; margin-top: 20px; color: green" class="urcom-button">' + translate("list.add") + '</div>');
addItem.on('click', addNewItem);
container.append(addItem);
const editButton = $('<div style="width: 100%; margin-top: 10px; color: orange" class="urcom-button">' + translate("list.edit") + '</div>');
editButton.on('click', editItem);
container.append(editButton);
const editList = $('<div style="width: 100%; margin-top: 10px; color: orange" class="urcom-button">' + translate("list.edit-name") + '</div>');
editList.on('click', renameList);
container.append(editList);
const dangerZone = $('<h5 style="margin-top: 20px; color:darkred">' + translate("list.danger") + '</h5>');
container.append(dangerZone);
let text;
if (DeleteTextMode) {
text = translate("list.cancel-delete");
} else {
text = translate("list.delete-response");
}
const deleteTextButton = $('<div style="width: 100%; margin-top: 10px; color: orangered" class="urcom-button">' + text + '</div>');
deleteTextButton.on('click', deleteTextItem);
container.append(deleteTextButton);
const deleteButton = $('<div style="width: 100%; margin-top: 10px; color: orangered" class="urcom-button">' + translate("list.delete-list") + '</div>');
deleteButton.on('click', deleteCustomList);
container.append(deleteButton);
}
}
} else {
// CurrentIndex is used to keep count of total arrays pairs which is used on the div's id tags
let CurrentIndex = 1;
// Go over the array and generate comment divs
for (let i = 0; i < URCommentsArray.length; i++) {
const comment = URCommentsArray[i];
addComments(container, CurrentIndex, comment)
// inc the CurrentIndex
CurrentIndex++;
}
}
// Add 2 br to the end of the list for lower resolution monitors
container.append('<br /><br />');
}
function addComments(container, CurrentIndex, commentObject) {
const title = commentObject.title ?? (commentObject.custom === 'new-line' ? '<br />' : '');
const urStatus = commentObject.status?.toLowerCase() ?? '';
const text = commentObject.response ?? '';
// Setup the comment color var
let textColor;
if (urStatus === "open") {
// Black
textColor = "#000000";
} else if (urStatus === "solved") {
// Green
textColor = "#008F00";
} else if (urStatus === "notidentified") {
// Orange
textColor = "#E68A00";
} else {
// Red - not defined and that is a problem
textColor = "#CC0000";
}
// Escaping titles and comments with escapeHtml(comment) so we can display items with special char as html;
let comment = text ? escapeHtml(text) : '';
let addClicks = false;
// normal comment link
let commentWrapper;
let clickText;
let doubleClickText;
if (!commentObject.custom) {
// This is a real button
commentWrapper = $('<div id="URComments-comment' + CurrentIndex + '" style="margin: 5px 0; border: 1px solid rgba(27, 31, 35, 0.15); border-radius: 6px; box-shadow: rgba(27, 31, 35, 0.04) 0 1px 0, rgba(255, 255, 255, 0.25) 0 1px 0 inset; background-color: #FAFBFC; cursor: pointer; font-size: 14px; font-weight: 500; line-height: 20px; list-style: none; padding: 3px 10px; position: relative; transition: background-color 0.2s cubic-bezier(0.3, 0, 0.5, 1);">');
if (DeleteTextMode) {
commentWrapper.css("border-color", "darkred");
commentWrapper.css("background-color", "orangered");
} else if (TextEditIndex === -1) {
commentWrapper.css("background-color", "yellow");
}
addClicks = true;
} else {
// These are titles/empty lines
commentWrapper = $('<div id="URComments-comment' + CurrentIndex + '"></div>')
}
if (commentObject.custom === "title") {
const titleHeader = $('<h5 style="color:' + textColor + '; text-decoration: underline; margin-top:15px;" title="title: ' + title + ' Action: ' + urStatus + '; comment: ' + comment + ' ">' + title + '</h5>');
commentWrapper.append(titleHeader);
} else {
clickText = $('<a class="URComments" style="color:' + textColor + '" title="title: ' + title + ' Action: ' + urStatus + '; comment: ' + comment + ' ">' + title + '</a>');
commentWrapper.append(clickText);
if (commentObject.custom !== "new-line") {
if (commentObject.urType === -2 && options.DBLClk7DCAutoSend || options.DBLClkAll) {
doubleClickText = $('<a id="URComments-commentDBLCLK' + CurrentIndex + '" class="URComments" style="color:' + textColor + '" title="' + translate("options.double-click.tooltip", { title }) + '"> ' + translate("options.double-click.title") + '</a>');
commentWrapper.append('<br />').append(doubleClickText);
}
}
}
// Add comment to list
container.append(commentWrapper);
if (addClicks) {
if (DeleteTextMode) {
commentWrapper.on('click', executeDeleteTextItem(CurrentIndex));
} else if (TextEditIndex === -1) {
commentWrapper.on('click', selectEditItem(CurrentIndex));
} else if (!TextEditIndex) {
// Set urID to zero so we don't freak out the functions expecting a UR ID
let urID = 0;
// Create the click function for each comment
commentWrapper.on('click', autoZoomIN(title, text, urStatus, urID));
// Create the double click function for each comment
if (doubleClickText) {
// Use this to click send automatically
doubleClickText.on('dblclick', autoZoomIN(title, text, urStatus, urID, "AutoSendComment"));
}
}
}
}
function addOptions(container) {
// Language select
addDropdownSettings(container, "", "settings.language.title", 'Language', SupportedLanguages, changeLanguage);
const settings = $('<h4 style="margin-top: 20px;">' + translate("tabs.settings") + '</h4>');
container.append(settings);
// Auto Reply
addBooleanSettings(container, "settings.auto-comment.tooltip", "settings.auto-comment.title", 'AutoSetNewComment');
// Automated Reminder / Closure
addBooleanSettings(container, "settings.auto-reminder.tooltip", "settings.auto-reminder.title", 'UrCommentAutoSet4dayComment');
// Zoom in on open
addBooleanSettings(container, "settings.auto-zoom.tooltip", "settings.auto-zoom.title", 'NewZoomIn');
// Auto Change State
addBooleanSettingsCallback(container, "settings.auto-status.tooltip", "settings.auto-status.title", 'AutoClickURStatus', (event) => {
toggleBoolean(event);
if (!options.AutoClickURStatus && options.SaveAfterComment) {
options.SaveAfterComment = false;
}
if (options.DBLClk7DCAutoSend || options.DBLClkAll) {
alert(translate("prompts.require-auto-click")); //"URComments to use the double click links you must have the autoset UR status option enabled"
options.AutoClickURStatus = true;
}
saveOptions(options);
refreshUI();
});
// Auto Save On Close
addBooleanSettingsCallback(container, "settings.auto-save.tooltip", "settings.auto-save.title", 'SaveAfterComment', (event) => {
toggleBoolean(event);
if (options.SaveAfterComment && !options.AutoClickURStatus) {
// This is required!
options.AutoClickURStatus = true;
saveOptions(options);
refreshUI();
}
});
// Auto Close UR Screen
addBooleanSettings(container, "settings.auto-close.tooltip", "settings.auto-close.title", 'UrCommentAutoCloseComment');
// Zoom after close
addBooleanSettings(container, "settings.auto-zoom-close.tooltip", "settings.auto-zoom-close.title", 'ZoomOutAfterComment');
// Switch to comment tab auto
addBooleanSettings(container, "settings.auto-tab.tooltip", "settings.auto-tab.title", 'AutoSwitchToURCommentsTab');
// Double clicking the 7 day close comment will auto send the 7 day close comment
addBooleanSettingsCallback(container, "settings.double-click-close.tooltip", "settings.double-click-close.title", 'DBLClk7DCAutoSend', (event) => {
toggleBoolean(event);
if (options.DBLClk7DCAutoSend) {
// This is required!
options.AutoClickURStatus = true;
saveOptions(options);
refreshUI();
}
});
// Double clicking comments will auto send comments
addBooleanSettingsCallback(container, "settings.double-click-send.tooltip", "settings.double-click-send.title", 'DBLClkAll', (event) => {
toggleBoolean(event);
if (options.DBLClkAll) {
// This is required!
options.AutoClickURStatus = true;
saveOptions(options);
refreshUI();
}
});
// Disable Next Button
addBooleanSettings(container, "settings.disable-buttons.tooltip", "settings.disable-buttons.title", 'UrCommentDisableURDoneBtn');
// Enable or disable ur pill counts
//addBooleanSettingsCallback(container, "settings.pill.tooltip", "settings.pill.title", 'URCommentsPillEnabled', (event) => {
// toggleBoolean(event);
// FilterURs();
//});
// Hide the AA description
addBooleanSettings(container, "settings.hide-aa.tooltip", "settings.hide-aa.title", 'HideAADescription');
// Days used to filter UR (reminder days / close days)
addTextNumberSettings(container, "", "settings.reminder-days.title", "ReminderDays");
addTextNumberSettings(container, "", "settings.close-days.title", "CloseDays");
// Greeting
addTextAreaSettings(container, "settings.greeting.tooltip", "settings.greeting.title", 'Greeting');
// Signature
addTextAreaSettings(container, "settings.signature.tooltip", "settings.signature.title", 'Signature');
const contactLabel = $('<div class="urcom-option"><span Title="' + translate("settings.credits.tooltip") + '" style="padding-bottom: 10px; line-height: 15px; font-weight: bold;"><br>' + translate("settings.credits.title") + ' :</span></div>');
container.append(contactLabel);
const report = $('<div class="urcom-option"><span Title="' + translate("settings.report.tooltip") + '" style="line-height: 15px;"><a href="https://gitlab.com/WMEScripts/URComments-French/-/issues" target="_blank">' + translate("settings.report.title") + '</a></span></div>'); // Maintainer
container.append(report);
const maintainer = $('<div class="urcom-option"><span Title="' + translate("settings.maintainer.tooltip") + '" style="line-height: 15px;">' + URC_img_waze_editor + translate("settings.maintainer.title") + ': @GyllieGyllie</span></div>'); // Maintainer
container.append(maintainer);
const founder = $('<div class="urcom-option"><span Title="' + translate("settings.founder.tooltip") + '" style="line-height: 15px;">' + URC_img_waze_editor + translate("settings.founder.title") + ': @tunisiano187</span></div>'); // Dev
container.append(founder);
}
// Save what comment list is selected
function changeLanguage(event) {
const selected = event.target.value;
if (selected !== "") {
options.Language = selected;
saveOptions(options);
refreshUI();
}
}
// Save what custom comment list is selected
function changeCustomTextList(event) {
const selected = event.target.value;
if (selected === translate("list.new")) {
addCustomList();
} else if (selected !== "") {
if (selected.startsWith("* ")) {
options.CustomTextList = selected.replace("* ", "");
saveOptions(options);
loadResponses().then(refreshUI);
} else {
options.CustomTextList = selected;
saveOptions(options);
loadCustomText(() => {
refreshUI();
})
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////
//// Option Logic
////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
function getDefaultOptions() {
return {
AutoSetNewComment: true,
UrCommentAutoSet4dayComment: true,
NewZoomIn: true,
AutoClickURStatus: true,
SaveAfterComment: true,
UrCommentAutoCloseComment: true,
ZoomOutAfterComment: true,
AutoSwitchToURCommentsTab: true,
DBLClk7DCAutoSend: false,
DBLClkAll: false,
UrCommentDisableURDoneBtn: true,
HideAADescription: true,
Signature: "",
Greeting: "",
URComShowPS: false,
URCommentsPS: "",
BoilerPlateCreators: "URComDefault",
URCommentsFilterEnabled: true,
URCommentsPillEnabled: true,
URCommentsHideNotMyUR: true,
URCommentsShowPastClose: true,
URCommentsHideInbetween: true,
URCommentsHideReminderNeeded: false,
URCommentsHideReplies: false,
URCommentsHideCloseNeeded: false,
URCommentsHideInital: false,
URCommentsHideWithoutDescript: false,
URCommentsHideWithDescript: false,
URCommentsHideClosed: true,
ReminderDays: 4,
CloseDays: 3,
CustomTextList: '',
Language: "English",
}
}
function loadOptions() {
let text = localStorage.getItem("URCom-Options");
let options;
if (text) {
options = JSON.parse(text);
} else {
options = getDefaultOptions();
migrate = true;
}
return options;
}
function validateOptions(options) {
const defaultOptions = getDefaultOptions();
// Add missing options
for (let key in defaultOptions) {
if (!(key in options)) {
options[key] = defaultOptions[key]
}
}
if (options.DBLClkAll) {
options.AutoClickURStatus = true;
}
if (options.DBLClk7DCAutoSend) {
options.AutoClickURStatus = true;
}
if (isNaN(options.ReminderDays) || options.ReminderDays < 0) {
options.ReminderDays = 0;
}
if (isNaN(options.CloseDays) || options.CloseDays < 0) {
options.CloseDays = 0;
}
if (options.CustomTextList === "None") {
options.CustomTextList = "Default";
}
}
function saveOptions(options) {
const optionsJson = JSON.stringify(options);
localStorage.setItem("URCom-Options", optionsJson);
}
function toggleBoolean(event) {
options[event.target.id] = event.target.checked;
saveOptions(options);
}
function changeText(event) {
options[event.target.id] = event.target.value;
saveOptions(options);
}
function migrateOptions() {
migrateTextOption('BoilerPlateCreators', 'BoilerPlateCreators');
migrateBooleanOptions('AutoSetNewComment', 'AutoSetNewComment');
migrateBooleanOptions('UrCommentAutoSet4dayComment', 'UrCommentAutoSet4dayComment');
migrateBooleanOptions('UrCommentAutoCloseComment', 'UrCommentAutoCloseComment');
migrateBooleanOptions('NewZoomIn', 'NewZoomIn');
migrateBooleanOptions('AutoClickURStatus', 'AutoClickURStatus');
migrateBooleanOptions('SaveAfterComment', 'SaveAfterComment');
migrateBooleanOptions('ZoomOutAfterComment', 'ZoomOutAfterComment');
migrateBooleanOptions('AutoSwitchToURCommentsTab', 'AutoSwitchToURCommentsTab');
migrateBooleanOptions('DBLClk7DCAutoSend', 'DBLClk7DCAutoSend');
migrateBooleanOptions('DBLClkAll', 'DBLClkAll');
migrateBooleanOptions('UrCommentDisableURDoneBtn', 'UrCommentDisableURDoneBtn');
migrateTextOption('Signature', 'Signature');
migrateBooleanOptions('URComShowPS', 'URComShowPS');
migrateTextOption('URCommentsPS', 'URCommentsPS');
migrateBooleanOptions('URCommentsFilterEnabled', 'URCommentsFilterEnabled');
migrateBooleanOptions('URCommentsPillEnabled', 'URCommentsPillEnabled');
migrateBooleanOptions('URCommentsHideNotMyUR', 'URCommentsHideNotMyUR');
migrateBooleanOptions('URCommentsShowPastClose', 'URCommentsShowPastClose');
migrateBooleanOptions('URCommentsHideInbetween', 'URCommentsHideInbetween');
migrateBooleanOptions('URCommentsHideReminderNeeded', 'URCommentsHideReminderNeeded');
migrateBooleanOptions('URCommentsHideReplies', 'URCommentsHideReplies');
migrateBooleanOptions('URCommentsHideCloseNeeded', 'URCommentsHideCloseNeeded');
migrateBooleanOptions('URCommentsHideInital', 'URCommentsHideInital');
migrateBooleanOptions('URCommentsHideWithoutDescript', 'URCommentsHideWithoutDescript');
migrateBooleanOptions('URCommentsHideWithDescript', 'URCommentsHideWithDescript');
migrateBooleanOptions('URCommentsHideClosed', 'URCommentsHideClosed');
migrateNumericOption('ReminderDays', 'ReminderDays');
migrateNumericOption('CloseDays', 'CloseDays');
saveOptions(options);
}
function migrateBooleanOptions(oldOption, newOption) {
const value = localStorage.getItem(oldOption);
if (value !== null && value !== undefined) {
options[newOption] = value === "yes";
}
}
function migrateNumericOption(oldOption, newOption) {
const value = localStorage.getItem(oldOption);
if (value !== null && value !== undefined) {
const number = Number(value);
if (!isNaN(number)) {
options[newOption] = number;
}
}
}
function migrateTextOption(oldOption, newOption) {
const value = localStorage.getItem(oldOption);
if (value !== null && value !== undefined) {
options[newOption] = value;
}
}
function addDropdownSettings(container, title, label, name, values, callback) {
let currentValue = options[name];
const wrapper = $('<div class="urcom-option" title="' + translate(title) + '"></div>');
wrapper.append('<span>' + translate(label) + '</span>');
wrapper.append('<br />');
const select = $('<select name="' + name + '" id="' + name + '" style="width: 100%;"></select>');
for (let i = 0; i < values.length; i++) {
select.append('<option value="' + values[i] + '" ' + (currentValue === values[i].replace("* ", "") ? 'selected="selected"' : '') + '>' + values[i] + '</option>');
}
// Create call back for the select
select.on('change', callback);
wrapper.append(select);
container.append(wrapper);
}
function addBooleanSettings(container, title, label, name) {
addBooleanSettingsCallback(container, title, label, name, toggleBoolean);
}
function addBooleanSettingsCallback(container, title, label, name, clickHandler) {
const currentValue = options[name];
const checkbox = $('<wz-checkbox id="' + name + '" Title="' + translate(title) + '" name="types" disabled="false" checked="' + currentValue + '">' + translate(label) + '</wz-checkbox>');
const optionHtml = $('<div class="urcom-option"></div>').append(checkbox);
container.append(optionHtml);
checkbox.on('click', clickHandler);
}
function addTextNumberSettings(container, title, label, name) {
const currentValue = options[name];
const textInput = $('<wz-text-input type="number" min="0" max="999" id="' + name + '" value="' + currentValue + '"></wz-text-input>');
const optionHtml = $('<div class="urcom-option"><span Title="' + translate(title) + '">' + translate(label) + '</span></div>').append(textInput);
container.append(optionHtml);
textInput.on('change', changeText);
}
function addTextAreaSettings(container, title, label, name) {
const currentValue = options[name];
const textArea = $('<wz-textarea id="' + name + '" style="height: 130px; width: 270px;" value="' + currentValue + '"></wz-textarea>');
const optionHtml = $('<div class="urcom-option"><span Title="' + translate(title) + '">' + translate(label) + '</span></div>').append(textArea);
container.append(optionHtml);
textArea.on('change', changeText);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////
//// UR Comment functions
////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
function addCustomList() {
let name = prompt("Enter the name for your list");
if (!name) {
refreshUI();
return;
}
// Make sure it doesn't exist
if (CustomLists.indexOf(name) >= 0) {
alert(translate("prompts.list-name-exists"));
return;
}
// Insert into the DB
const objectStore = DB
.transaction("custom_lists", "readwrite")
.objectStore("custom_lists");
objectStore.add({
name: name,
order: CustomLists.length - 2,
responses: []
});
CustomLists.splice(CustomLists.length - 1, 1);
CustomLists.push(name);
CustomLists.push(translate("list.new"));
options.CustomTextList = name;
saveOptions(options);
CustomListText = [];
refreshUI();
alert(translate("prompts.list-created"));
}
function renameList() {
let name = prompt(translate("prompts.list-enter-name"), options.CustomTextList);
if (!name) {
return;
}
// Make sure it doesn't exist
if (CustomLists.indexOf(name) >= 0) {
alert(translate("prompts.list-name-exists"));
return;
}
const objectStore = DB
.transaction("custom_lists", "readwrite")
.objectStore("custom_lists");
const request = objectStore.get(options.CustomTextList);
request.onerror = (event) => {
console.log(event);
alert(translate("prompts.list-update-failed"));
};
request.onsuccess = (event) => {
const data = event.target.result;
data.name = name;
const requestUpdate = objectStore.add(data);
requestUpdate.onerror = (event) => {
console.log(event);
alert(translate("prompts.list-update-failed"));
};
requestUpdate.onsuccess = (event) => {
objectStore.delete(options.CustomTextList);
const index = CustomLists.indexOf(options.CustomTextList);
CustomLists[index] = name;
options.CustomTextList = name;
saveOptions(options);
refreshUI();
}
}
}
function cancelTextEdit() {
ShowTextEditFields = false;
TextEditIndex = undefined;
refreshUI();
}
function saveCustomText() {
const titleInput = $("#customTextTitle")[0];
const textInput = $("#customTextText")[0];
const statusSelect = $("#customTextStatus")[0];
const title = titleInput.value;
const text = textInput.value;
const statusIndex = statusSelect.selectedIndex;
let status;
switch (statusIndex) {
case 0:
default:
status = "open";
break;
case 1:
status = "closed";
break;
case 2:
status = "notidentified";
break;
}
if (!title || !text || !status) {
alert(translate("prompts.missing-data"));
return;
}
const objectStore = DB
.transaction("custom_lists", "readwrite")
.objectStore("custom_lists");
const request = objectStore.get(options.CustomTextList);
request.onerror = (event) => {
alert(translate("prompts.response-failed"));
};
request.onsuccess = (event) => {
const data = event.target.result;
if (TextEditIndex !== undefined && TextEditIndex !== -1) {
// Update text
data.responses.forEach(response => {
if (response.sorting === TextEditIndex) {
response.name = title;
response.text = text;
response.status = status;
}
})
} else {
data.responses.push({
sorting: CustomListText.length,
name: title,
text: text,
status: status,
})
}
const requestUpdate = objectStore.put(data);
requestUpdate.onerror = (event) => {
alert(translate("prompts.response-failed"));
};
requestUpdate.onsuccess = (event) => {
ShowTextEditFields = false;
TextEditIndex = undefined;
loadCustomText(() => {
refreshUI();
});
}
}
}
function deleteCustomList() {
const result = confirm(translate("prompts.confirm-delete-list"));
if (!result) {
return;
}
const objectStore = DB
.transaction("custom_lists", "readwrite")
.objectStore("custom_lists");
const request = objectStore.delete(options.CustomTextList);
request.onerror = (event) => {
alert(translate("prompts.delete-list-failed"));
};
request.onsuccess = (event) => {
// Fall back to default list
CustomLists = CustomLists.filter(name => name !== options.CustomTextList);
CustomListText = [];
// Switch back to default list
options.CustomTextList = defaultLists.keys().next().value;
console.log("[URCom] Fallback to " + options.CustomTextList + " after list delete");
saveOptions(options);
loadResponses().then(refreshUI);
}
}
function deleteTextItem() {
DeleteTextMode = !DeleteTextMode;
refreshUI();
if (DeleteTextMode) {
showWMEMessage(translate("prompts.response-delete-click"), 5000);
}
}
function executeDeleteTextItem(index) {
return function() {
const text = CustomListText[index];
const objectStore = DB
.transaction("custom_lists", "readwrite")
.objectStore("custom_lists");
const request = objectStore.get(options.CustomTextList);
request.onerror = (event) => {
alert(translate("prompts.response-delete-failed"));
};
request.onsuccess = (event) => {
const data = event.target.result;
// Remove the one we don't need
data.responses = data.responses.filter(response => response.name !== text.name || response.text !== text.text || response.status !== text.status);
// Update sorting
for (let i = 0; i < data.responses.length; i++) {
data.responses[i].sorting = i;
}
const requestUpdate = objectStore.put(data);
requestUpdate.onerror = (event) => {
alert(translate("prompts.response-delete-failed"));
};
requestUpdate.onsuccess = (event) => {
DeleteTextMode = false;
loadCustomText(() => {
refreshUI();
});
}
}
}
}
function migrateDb(oldDb) {
return new Promise(async resolve => {
let migrating = true;
oldDb.transaction(async (tx) => {
await tx.executeSql('SELECT * FROM custom_comments', [], async function (tx, results) {
const len = results.rows.length;
console.log("[URCom] Migration found " + len + " existing lists");
for (let i = 0; i < len; i++) {
let migratingList = true;
const name = results.rows.item(i).name;
const responses = [];
await tx.executeSql('SELECT * FROM custom_comments_text WHERE list = ? ORDER BY sorting', [name], function (tx, results) {
const len = results.rows.length;
for (let j = 0; j < len; j++) {
const result = results.rows.item(j);
responses.push({
sorting: result.sorting,
name: result.name,
text: result.text,
status: result.status,
});
}
const objectStore = DB
.transaction("custom_lists", "readwrite")
.objectStore("custom_lists");
objectStore.add({
name: name,
order: i,
responses: responses
});
migratingList = false;
});
while (migratingList) {
await sleep(1);
}
}
migrating = false;
});
}, (error) => {
// Ignore since prolly table doesn't exist
migrating = false;
});
while (migrating) {
await sleep(1);
}
oldDb.transaction((tx) => {
tx.executeSql('DELETE FROM custom_comments', []);
});
resolve();
});
}
function addNewItem() {
ShowTextEditFields = true;
refreshUI()
}
function editItem() {
ShowTextOptionButtons = false;
TextEditIndex = -1;
refreshUI();
showWMEMessage(translate("prompts.response-edit-click"), 5000);
}
function selectEditItem(index) {
return async function() {
const text = CustomListText[index];
if (!text) {
TextEditIndex = undefined;
return;
}
ShowTextEditFields = true;
ShowTextOptionButtons = true;
TextEditIndex = index;
// Refresh first
await refreshUI();
// Then update the settings
const titleInput = $("#customTextTitle")[0];
const textInput = $("#customTextText")[0];
const statusSelect = $("#customTextStatus")[0];
titleInput.value = text.name;
textInput.value = text.text;
switch (text.status) {
case "open":
statusSelect.selectedIndex = 0;
break;
case "closed":
statusSelect.selectedIndex = 1;
break;
case "notidentified":
statusSelect.selectedIndex = 2;
break;
}
}
}
function escapeHtml(a) {
a = a.replace(/&/g, "&");
a = a.replace(/</g, "<");
a = a.replace(/>/g, ">");
a = a.replace(/"/g, """);
a = a.replace(/'/g, "'");
return a;
}
function autoZoomIN(title, comment, urStatus, urID, AutoSendComment) {
return function() {
let URCommentsUnsavedDetected = false;
const hasUnsavedChanges = wmeSDK.Editing.getUnsavedChangesCount();
// Detect unsaved changed if there are and the auto save option is on abort adding comments to the UR
if (hasUnsavedChanges > 0 && options.SaveAfterComment && urStatus.toLowerCase() !== "open") {
URCommentsUnsavedDetected = true;
alert(translate("prompts.unsaved-changes")); //"UrComments has detected that you have unsaved changes!\n\nWith the Auto Save option enabled and with unsaved changes you cannot send comments that would require the script to save. Please save your changes and then re-click the comment you wish to send."
}
// Get urID for manually clicked comments
if (urID === 0 || urID === "" || urID === undefined) {
urID = $(".map-problem.marker-selected").data("id");
}
// Check to see if the auto zoom in option is enabled, if it is start the zooming in process
if (options.NewZoomIn && AutoSendComment !== "AutoSendComment" && URCommentsUnsavedDetected === false) {
// Predefined zoom threshold for auto zoom
const zoom = 15;
// Do not zoom back out if we are already zoomed in and just happen to be re-clicking on a UR.
// or we have the map set good for a 4-day reminder
const WazeCurrentZoom = getWazeMapZoomLevel();
if (WazeCurrentZoom < zoom) {
goToURById(urID, zoom);
}
setTimeout(postURComment(title, comment, urStatus, AutoSendComment, urID), 1);
} else if (URCommentsUnsavedDetected === false) {
// auto zoom in is disabled jump to postURComment
// we have to use set timeout here because we need the return function() in PostURComment
// for when we are zooming in and out for the reminder
// since we are not zooming here jump rigth to PostURComment
setTimeout(postURComment(title, comment, urStatus, AutoSendComment, urID), 1);
}
};
}
function getWazeMapZoomLevel() {
return W.map.mapState.mapLocation.zoom;
}
function goToURById(urID, zoom) {
// save zoom so we can return this the current zoom level
ReturnToCurrentZoom = getWazeMapZoomLevel();
const geo = getUrById(urID).attributes.geometry;
W.map.getOLMap().moveTo([geo.x, geo.y], zoom);
}
function postURComment(title, comment, urStatus, autoSendComment, urID) {
// The user clicked on a comment link
return function() {
// Swap out special text
comment = stringSwap(comment, urID);
$('.new-comment-form .send-button').on('click', urCommentZoomOutCheck(title, urStatus));
// Check if the comment text area is present if not alert the user to open a UR
const commentArea = $($(".new-comment-text")[0]);
if (commentArea) {
commentArea.val(comment).change();
commentArea.keyup();
if(!$('.no-comments')) {
commentArea.css("backgroundColor","Yellow");
}
// Click the UR status
setTimeout(checkIfClickStatus(urStatus, autoSendComment), 100);
} else {
// We were unable to find an open UR
showWMEMessage(translate("prompts.no-comment-box"), 5000); //"URComments: Can not find the comment box! In order for this script to work you need to have a user request open."
}
};
}
function urCommentZoomOutCheck(Title, URStatus) {
return function() {
// This is the new place for zooming out and will still be happening while the comment is sending
if (options.ZoomOutAfterComment) {
setTimeout(setZoomCloseUR(ReturnToCurrentZoom, "LeaveOpen"), 0);
}
setTimeout(urCommentSendBtnClicked(Title, URStatus), 20);
}
}
function setZoomCloseUR(zoom, b) {
// This sets the map zoom; 0 is all the way out; 10 is all the way in but next to useless (the map and sat views disappear);
// the closest zoom that shows the sat and map is zoom 9
return function() {
W.map.setCenter(W.map.getCenter(), zoom);
// Close ur if zooming out to
if (b === "CloseUR") {
$('.close-panel')[0].click();
}
};
}
function stringSwap(string, urID) {
if (urID > 0) {
const ur = getUrById(urID);
string = string.replace("$URD", ur.attributes.typeText + ' : ' + ur.attributes.description);
string = string.replace(/ /g, "");
string = string.replace(/ /g, "");
//string = string.replace(/(\r\n|\n)/gm, "");
} else if ($(".description .content").length > 0) {
string = string.replace("$URD", $(".description .content").html());
string = string.replace(/ /g, "");
string = string.replace(/ /g, "");
//string = string.replace(/(\r\n|\n)/gm, "");
string = string.replace("$USERNAME", W.loginManager.user.getUsername());
} else if (string.indexOf("$URD") >= 0) {
string = string.replace(" \"$URD\"", "");
}
// Legacy, remove old signature
string = string.replace('$SIGNATURE', '');
const greeting = options.Greeting;
if (greeting && greeting !== "" && greeting !== null && greeting !== "undefined") {
string = greeting + "\r\n" + string;
}
const signature = options.Signature;
if (signature && signature !== "" && signature !== null && signature !== "undefined") {
string = string + "\r\n" + signature;
}
// Selected segments
let streetName = "";
if (W.selectionManager.getSelectedFeatures().length >= 1 && W.selectionManager.getSelectedFeatures().length <= 2) {
for (let i = 0; i < W.selectionManager.getSelectedFeatures().length; i++) {
if (W.selectionManager.getSelectedFeatures()[i].model.CLASS_NAME === "W.Feature.Vector.Segment") {
const primaryStreetID = W.selectionManager.getSelectedFeatures()[i].model.attributes.primaryStreetID;
if (i === 0) {
streetName = W.model.streets.objects[primaryStreetID].name;
} else {
streetName = "the intersection of " + streetName + " and " + W.model.streets.objects[primaryStreetID].name;
}
}
}
string = string.replace("$SELSEGS", streetName);
}
return string;
}
function urCommentSendBtnClicked(title, urStatus) {
// Waze is weird and after clicking send button the close button had to be refound, which takes a few seconds for the new close button to be drawn
// so we wait 1500 milliseconds before looking for the close button
// since we are passing vars to the next function we have to pass this to handler function so it doesn't happen on click
// The above is still true but what i have found is that it sometimes takes a while from clicking send to the comment actually posting.
// There was time when i closed the comment before it actually posted and it would have to be redone. So added a check and a timeout and recheck if the textarea isn't empty.
// Afterwards we can re-grab and click the close button
return function() {
// Grab the close button to compare to later
CloseButtonHolder = $(".problem-panel-navigation button.close-button");
// Check to see if the comments went through before saving or closing the comment
const textArea = $(".new-comment-text");
if (textArea.val() !== "" && textArea.val() !== undefined) {
setTimeout(urCommentSendBtnClicked(title, urStatus), 20);
} else {
closeUR(title, urStatus);
}
};
}
function closeUR(title, urStatus) {
return function() {
if (urStatus.toLowerCase() === "solved" || urStatus.toLowerCase() === "notidentified") {
// This clicks the waze save btn
if (options.AutoClickURStatus && options.SaveAfterComment) {
// Click save
$('.toolbar #save-button').trigger('click');
} else if (options.UrCommentAutoCloseComment) {
$('.close-panel')[0].click();
}
} else {
// When not saving you have to click close.
if (options.UrCommentAutoCloseComment) {
$('.close-panel')[0].click();
}
}
//this is the new place for zooming out and will still be happening while the comment is sending
//zoom out option - if the user option is set to reload map after posting a comment reply
if (options.ZoomOutAfterComment) {
//urcToConsole("zoom out closeUR");
setTimeout(setZoomCloseUR(ReturnToCurrentZoom, "LeaveOpen"), 0);
}
setTimeout(urcUREvent_onObjectsAdded('URCommentsReload'), 0);
};
}
function urcUREvent_onObjectsAdded(a) {
return function() {
// Check if the pill count are enabled otherwise abort this function
if (!options.URCommentsPillEnabled) {
return
}
if (a === "timedout" && window.HideUR === "running") {
window.HideUR = "stopped";
a = "timedout";
}
if (window.HideUR === "stopped" && a !== "timedout") {
clearTimeout(window.buffertedtimeout);
clearTimeout(window.buffertedtimeout2);
// Certain events need to be launched a bit later then others
if (a === "moveend" || a === "zoomend") {
window.buffertedtimeout = setTimeout(FilterURs, 2000);
} else {
window.buffertedtimeout = setTimeout(FilterURs, 500);
}
window.HideUR = "running";
window.BufferFillterURCommand = false;
window.buffertedtimeout2 = setTimeout(urcUREvent_onObjectsAdded("timedout"), 30000);
}
};
}
function FilterURs() {
const allUrs = W.model.mapUpdateRequests.objects;
const allUrIDs = Object.keys(allUrs);
// Abort filtering URs if the list is empty
if (allUrIDs.length === 0) {
window.HideUR = "stopped";
setTimeout(urcUREvent_onObjectsAdded("list is empty retry"), 5000);
return;
}
let allID = '';
let countInCurrentList = 0;
let delay = 0;
let languageCount = knownLanguages && knownLanguages.length;
for (let urID of allUrIDs) {
const ur = allUrs[urID];
const language = ur.attributes.reporterLanguage;
if (knownLanguages && knownLanguages.indexOf(language) === -1) {
knownLanguages.push(language);
}
// Make sure we can see the UR
if (onScreen(ur)) {
if (allID !== '') {
allID += ",";
}
allID = allID + urID;
countInCurrentList = countInCurrentList + 1;
}
// Batch the current list
if (countInCurrentList >= 500) {
// Send this batch in a timeout
setTimeout(FilterURs2(allID), delay);
countInCurrentList = 0;
allID = "";
delay = delay + 1000;
}
}
// Keep track of possible languages, to later support different list per ur language
if (knownLanguages && languageCount !== knownLanguages.length) {
const objectStore = DB
.transaction("data-store", "readwrite")
.objectStore("data-store");
const requestUpdate = objectStore.put({
id: "languages",
languages: knownLanguages
});
requestUpdate.onerror = (event) => {
console.log("[URCom] Failed to update known languages");
};
requestUpdate.onsuccess = (event) => {
console.log("[URCom] Updated known languages");
};
}
setTimeout(FilterURs2(allID), delay);
}
function FilterURs2(allID) {
return function() {
const CloseDays = options.CloseDays;
const ReminderDays = options.ReminderDays;
const ClosePlusReminderDays = CloseDays + ReminderDays;
const EditorID = W.loginManager.user.getID(); // Editor's id number
if (allID !== "") {
// This is the link that works but I think it is grabbing a cached version of the page
//https://www.waze.com/row-Descartes/app/MapProblems/UpdateRequests?ids=20006756
const urSessionURL = 'https://' + window.location.host + W.Config.api_base + '/MapProblems/UpdateRequests?ids=' + allID + '&time=' + (new Date()).getTime();
let LastCommenterUserID = '0';
// Send a request to load the UR data
$.ajax({
dataType: "json",
url: urSessionURL,
success: function(json) {
try {
const urs = json.updateRequestSessions.objects;
const layer = W.map.layers.find((layer) => layer.name === "update_requests");
for (let jsnObj = 0; jsnObj < urs.length; jsnObj++) {
const urDetail = urs[jsnObj];
const id = urDetail.id;
const ur = W.model.mapUpdateRequests.objects[id];
let skip = false;
let urStyle = 'shown';
let lastCommentDateTime = 0;
const numberOfComments = urDetail.comments.length;
let CountsBGColor = '#FFFF99'; // Light yellow
const urBubble = $('image#' + id);
if (numberOfComments > 0) {
let reporterResponded = false;
let LastComment = '';
for (let comment of urDetail.comments) {
if (comment.userID === -1) {
reporterResponded = true;
}
const commentText = comment.text;
lastCommentDateTime = comment.createdOn;
LastCommenterUserID = comment.userID;
LastComment = commentText;
// Only white if logged in editor has the last editor comment
if (LastCommenterUserID > 1) {
if (LastCommenterUserID === EditorID) {
CountsBGColor = "white";
} else {
CountsBGColor = "#FFFF99"; //light yellow
}
}
}
}
let lastCommentAge = uroDateToDays(lastCommentDateTime);
if (ur.attributes.open === false) {
skip = true;
}
if (skip === false && ur.type === "mapUpdateRequest") {
if (numberOfComments > 0) {
// Last comment was a user reply; change the pin color to blue or peach
if (LastCommenterUserID < 1) {
if (CountsBGColor === "white") {
CountsBGColor = "#79B5C7"; // Light blue
} else {
CountsBGColor = "#FFCC99"; // Peach
}
} else if (lastCommentAge > ClosePlusReminderDays && CountsBGColor !== "white") {
CountsBGColor = "#FF8B8B"; // Light red
}
if (CountsBGColor === "#FFFF99" && numberOfComments >= 1 && lastCommentAge >= ClosePlusReminderDays && LastCommenterUserID > 1) {
CountsBGColor = "#FF8B8B"; // Light red
}
}
}
if (lastCommentAge === undefined) {
lastCommentAge = "?";
}
let Message = numberOfComments + UrCommentsTextPic + " " + lastCommentAge + UrCommentsTimePic;
// If the ur has more than 0 comments reorder the ur stacking
if (numberOfComments > 0) {
let MessageOffset = Message.length;
MessageOffset = MessageOffset - (UrCommentsTextPic.length - 3)
MessageOffset = MessageOffset - (UrCommentsTimePic.length - 4)
if (MessageOffset < 10) {
MessageOffset = MessageOffset * 1.4;
} else {
MessageOffset = MessageOffset * 2.3;
}
MessageOffset = "-" + MessageOffset + "px";
if (CountsBGColor === "#CCCCCC") { // Light grey
urBubble.css({
'z-index': '999'
});
} else if (CountsBGColor === "white" || CountsBGColor === "#79B5C7") {
urBubble.css({
'z-index': '998'
});
//).style.visibility
} else if (CountsBGColor === "#FF8B8B") { // Light red
urBubble.css({
'z-index': '997'
});
}
/*
CountsBGColor = "#FFFF99"; //light yellow = UR that are waiting for the last editor but still has time before the Close days setting ex 7 days
CountsBGColor = "#CCCCCC"; //light grey = URO styled notes ex [NOTE]
CountsBGColor = "#FFCC99"; //peach = another editor before the close days has gone by has user reply
CountsBGColor = "#FF8B8B"; //light red = past the close days setting and is now able to be taken over by another editor
CountsBGColor = "white"; = UR that "belong to the editor logged in that need work
CountsBGColor = "#79B5C7"; //light blue = UR that "belong to the editor logged in that have user replies
White = The editor logged in has comments on the UR and the UR needs work
light blue = The editor logged in has comments on the UR and the UR's last comment was a user reply
light red = past the close days setting and is now able to be taken over by another editor
light yellow = UR that are waiting for the another editor to send a reminder or to be closed but still has time before the Close days setting (ex 7 days)
peach = UR that another editor had commented on but the last comment is a user reply
*/
if (options.URCommentsPillEnabled) {
const featureId = layer.features.find((feature) => feature.attributes.wazeFeature.id === id).geometry.id;
const urCountBubble = $('image#' + featureId);
// Add URC bubble
if (urCountBubble.hasClass('URCounts') === false) {
urBubble.append($("<div>").css("clear", "both")
.css("margin-bottom", "10px")
.append($("<div>").html(Message)
.css("color", "black")
.css("background", CountsBGColor)
.css("position", "absolute")
.css("top", "30px")
.css("height", "18px")
.css("right", MessageOffset)
.css("display", "block")
.css("width", "auto")
.css("white-space", "nowrap")
.css("padding-left", "5px")
.css("padding-right", "5px")
.css("border", "1px solid")
.css("border-radius", "25px")
.addClass('URCounts')
)
);
} else {
urCountBubble.html(Message);
urCountBubble.css("background", CountsBGColor);
urCountBubble.css("right", MessageOffset);
}
// End of URC bubble
}
}
urStyle = 'visible';
urBubble.css("visibility", urStyle);
}
window.HideUR = "stopped";
} catch (e) {
console.log(e);
setTimeout(FilterURs, 1000);
}
}
});
} else {
window.HideUR = "stopped";
}
};
}
function onScreen(obj) {
// Geometry was removed from W.model.mapUpdateRequests.objects[id]
// but can be found in W.model.mapUpdateRequests.objects[id].geometry
const geo = obj.getOLGeometry();
if (geo) {
return W.map.getExtent().intersectsBounds(geo.getBounds());
}
return false;
}
function uroDateToDays(dateToConvert) {
const dateNow = new Date();
const elapsedSinceEpoch = dateNow.getTime();
const elapsedSinceEvent = elapsedSinceEpoch - dateToConvert;
dateNow.setHours(0);
dateNow.setMinutes(0);
dateNow.setSeconds(0);
dateNow.setMilliseconds(0);
const elapsedSinceMidnight = elapsedSinceEpoch - dateNow.getTime();
if (elapsedSinceEvent < elapsedSinceMidnight) {
// event occurred today...
return 0;
} else {
// event occurred at some point prior to midnight this morning, so return a minimum value of 1...
return 1 + Math.floor((elapsedSinceEvent - elapsedSinceMidnight) / 86400000);
}
}
function uroGetCommentAge(commentObj) {
if (commentObj.createdOn === null) {
return -1;
}
return uroDateToDays(commentObj.createdOn);
}
function showWMEMessage(message, delay) {
const dateNow = new Date();
let TrickRemove = dateNow.getTime();
const width = message.length * 10;
// Message holder div
const c = '<div id="URCMessage" style="width: 100%; font-size: 15px; font-weight: bold; margin-left: auto; margin-right: auto; position: absolute; top: 0; left: 10px; z-index: 1000;"></div>';
$("#map").append(c);
// Message div
const d = '<div id="URCMapNote' + TrickRemove + '" style="width: ' + width + 'px; font-size: 15px; font-weight: bold; margin-left: auto; margin-right: auto; background-color: orange;"><center><b>' + message + '</b></center></div>';
$("#URCMessage").append(d);
// Remove messages after the duration has passed
$("#URCMapNote" + TrickRemove).show().delay(delay).queue(function(n) {
$(this).remove();
n();
});
}
function checkIfClickStatus(URStatus, AutoSendComment) {
return function() {
if (options.AutoClickURStatus) {
// Bypass the confirm function so other site messages do not come up!
confirmToConsole();
const openInput = $("input[value='open']");
// Click the ur status options (Not identified solved, open)
if (openInput) {
if (URStatus.toLowerCase() === "notidentified") {
// Click Not identified
$("input[value='not-identified']")[0].click();
} else if (URStatus.toLowerCase() === "solved") {
// Click solved
$("input[value='solved']")[0].click();
} else {
// Click back on open just encase the wrong reply was clicked previously
openInput[0].click();
}
}
// Restores confirm function so other site messages come up!
restoreConfirmToConfirm();
}
if (AutoSendComment === "AutoSendComment") {
setTimeout(uRVerifyStatusSet(URStatus, AutoSendComment), 1);
}
};
}
function confirmToConsole() {
// Override the default action of the standard confirm by writing confirm to a new function nconfirm, making a 'fake' confirm and then restoring confirm by copying the nconfirm back over confirm!
nConfirm = confirm;
confirm = function(msg) {
// if ((I18n.translations[I18n.locale].update_requests.panel.confirm == msg) && (uroGetCBChecked('_cbDisablePendingQuestions') == true)) {
// urcToConsole('URComment confirm redirected to console: ' + msg);
return true;
};
}
function restoreConfirmToConfirm() {
// Restore the normal action of confirm by writing nconfirm to back over confirm, so the site is able to send user messages outside of my script!
confirm = nConfirm;
}
function uRVerifyStatusSet(URStatus, AutoSendComment) {
return function() {
let URStatusOk = true;
if (options.AutoClickURStatus) {
if (URStatus.toLowerCase() === "notidentified") {
// Click Not identified
if ($("input[value='not-identified']").is(":checked") === false) {
URStatusOk = false;
}
} else if (URStatus.toLowerCase() === "solved") {
// Click solved
if ($("input[value='solved']").is(":checked") === false) {
URStatusOk = false;
}
} else {
// Click back on open just encase the wrong reply was clicked previously
if ($("input[value='open']").is(":checked") === false) {
URStatusOk = false;
}
}
}
if (URStatusOk) {
setTimeout(autoClickSend(URStatus, AutoSendComment), 10);
} else {
setTimeout(uRVerifyStatusSet(URStatus, AutoSendComment), 150);
}
};
}
function autoClickSend(URStatus, AutoSendComment) {
return function() {
if (AutoSendComment === "AutoSendComment") {
$('.new-comment-form .send-button').trigger('click');
}
};
}
// This is the small crosshair in the UR window
function crossHairsClicked(urID, zoom) {
return function() {
setTimeout(() => goToURById(urID, zoom), 100);
};
}
function getUrById(id) {
/*
const urs = W.model.mapUpdateRequests.getObjectArray();
for (let i = 0; i < urs.length; i++) {
if (urs[i].attributes?.id === id) {
return urs[i];
}
}
return null;
*/
return W.model.mapUpdateRequests.objects[id];
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
//Make HTTP Requests
function makeHTTPRequest(type, url) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: type,
url: url,
headers: {"Referer": document.location.href},
onload: (response) => {
resolve(JSON.parse(response.response));
},
onerror: (error) => {
reject(error);
}
});
});
}
function translate(s, data) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
let current = translation;
const a = s.split('.');
for (let i = 0, n = a.length; i < n; ++i) {
let k = a[i];
if (k in current) {
current = current[k];
} else {
return s;
}
}
if (current && data) {
for (const [key, value] of Object.entries(data)) {
current = current.replace("{{" + key + "}}", value);
}
}
return current;
}
///////////////////////////////////////////////////////////////////////////////////
//////
////// Background task(s)
//////
///////////////////////////////////////////////////////////////////////////////////
// Look for the UR window to be open
function lookForOpenedUR() {
// Relaunch checking for open ur - moved this up here so the script would keep trying if I had an error
setTimeout(lookForOpenedUR, 500);
let urID = W.map.getLayerByName('update_requests').features.filter((feature) => feature.attributes.wazeFeature.isSelected)[0]?.attributes?.wazeFeature?.id;
if (typeof urID !== 'undefined' && urID > 0) {
// New or same ur (re)open(ed) so now we can do stuff; this prevents this function to continuously applying settings to a ur
if (UrCommentLasturID !== urID && $(".new-comment-text").length !== 0) {
// grab the current UR ID for next time
UrCommentLasturID = urID;
// Auto expand ur comments list and text area
const conversation = $("#panel-container .problem-edit .conversation");
if (conversation.length !== 0) {
conversation.removeClass('collapsed');
}
// Auto expand ur comments description
const description = $("#panel-container .problem-edit .description");
if (description.length !== 0) {
description.removeClass('collapsed');
if (options.HideAADescription) {
const content = $("#panel-container .problem-edit .description .content");
if (content.length !== 0) {
let contentText = content.text();
// Does the AA tag exist?
if (contentText.indexOf("Reported from AAOS") >= 0) {
if (contentText === "Reported from AAOS") {
// Full description so just hide it
description.css("display", "none");
} else {
// Subtract if from the content
content.text(contentText.replace("Reported from AAOS", ""));
}
}
}
}
}
// Disable the stupid buttons at the bottom of the UR window done / next
const nextButton = $("#panel-container .content .navigation");
if (nextButton.length > 0 && options.UrCommentDisableURDoneBtn) {
nextButton.css('display', 'none');
}
// Attach an even listener to the UR center button to take us to the UR
$('#panel-container .header .panel-header-actions .focus').on('click', crossHairsClicked(urID, 15));
const UR = getUrById(urID);
// Grab the report language
const language = W.model.mapUpdateRequests.objects[urID].attributes.reporterLanguage;
console.log("[URCom] Report language is: " + language);
// Autofill in comment
// Check what type of message to insert into the ur
let comments;
if (W.model.updateRequestSessions.objects[urID].hasOwnProperty('comments')) {
comments = W.model.updateRequestSessions.objects[urID].comments;
} else {
comments = W.model.updateRequestSessions.objects[urID].attributes.comments;
}
const commentCount = comments.length;
// If number of comment is zero assume this is a new ur
if (!UR.attributes.hasComments) {
const noPermissionAlert = $(".no-permissions-alert").length > 0;
// Initial, zero comments
if (options.AutoSetNewComment && !noPermissionAlert) {
// This will be on of the types of UR that a user can choose from when submitting a UR
const urType = UR.attributes.type;
console.log("[URCom] UR Type: " + urType);
if (options.CustomTextList && !defaultLists.has(options.CustomTextList)) {
for (let i = 0; i < CustomListText.length; i++) {
let text = CustomListText[i];
if (text.name.toLowerCase().replace('.', '') === translate("ur-types." + urType).toLowerCase()) {
let reply = text.text;
setTimeout(autoZoomIN(text.name, reply, text.status, urID), 0);
break;
}
}
} else {
// Loop through the comment array for a comment that matches the request type.
for (let i = 0; i < URCommentsArray.length; i++) {
const comment = URCommentsArray[i];
if (comment.urType === "" + urType) {
setTimeout(autoZoomIN(comment.title, comment.response, comment.status, urID), 0);
break;
}
}
}
//var inmyzone = 1;
} else if (noPermissionAlert){
//$(".new-comment-text").prop('disabled', true);
//$(".send-button").hide();
//var inmyzone = 0;
}
} else {
// Reminder & close section
const LastCommenterUserID = comments[comments.length - 1].userID;
// uro days old
let commentDaysOld = uroGetCommentAge(comments[commentCount - 1]);
// Do we want to auto set reminders
if (options.UrCommentAutoSet4dayComment) {
// -- REMINDER SECTION -- \\
const ReminderDays = options.ReminderDays;
// Only 1 comment has been added, reminder days is higher than 0, reminder days has passed, and comment isn't from reporter (aka userid != -1)
if (commentCount === 1 && ReminderDays > 0 && commentDaysOld >= ReminderDays && LastCommenterUserID > 1) {
const comment = URCommentsArray.find((c) => c.urType === "-1");
setTimeout(autoZoomIN(comment.title, comment.response, comment.status, urID), 0);
}
// -- CLOSE SECTION -- \\
const CloseDays = options.CloseDays;
if (commentCount > 1 && CloseDays > 0 && commentDaysOld >= CloseDays && LastCommenterUserID > 1) {
const comment = URCommentsArray.find((c) => c.urType === "-2");
setTimeout(autoZoomIN(comment.title, comment.response, comment.status, urID), 0);
}
}
// Don't allow auto filling of the close message because it clicks the not identified option and causes trouble when the Ur window is shut/closed the next save will mark it as not identified, without a comment.
}
/*if ($(".no-permissions-alert")[0] || $(".close-details")[0]){
$(".new-comment-text").prop('disabled', true);
$(".new-comment-text").hide();
$(".send-button").hide();
}*/
/*if($(".new-comment-text").val()==="" && URComSignature.trim()!=="")
{
$(".new-comment-text").val("\n\n" + URComSignature);
}*/
const WazeCurrentZoom = getWazeMapZoomLevel();
// Predefined zoom threshold for auto zoom
const zoom = 15;
if (commentCount === 0 && options.NewZoomIn) {
// Zoom in new
// Do not zoom back out if we are already zoomed in and just happen to be re-clicking on a UR.
if (WazeCurrentZoom < zoom) {
goToURById(urID, zoom);
}
}
// Jump to bottom in full UR section
const topSection = $('.problem-data').parent();
topSection.scrollTop(topSection[0].scrollHeight);
// Jump to bottom in conversation section
const conversationSection = $('.conversation-view .comment-list');
conversationSection.scrollTop(conversationSection[0].scrollHeight);
// Auto switch to ur comments tab
if (options.AutoSwitchToURCommentsTab) {
// Grab the active tab
PreviousTab = $("#user-tabs > ul > li.active > a");
// Grab the active tabs scroll position
const tabContent = $('#sidebar div.tab-content');
PreviousTabPosition = tabContent.scrollTop();
tabContent.scrollTop(0); // Reset scroll pos
// Open the scripts tab
if (!$("[data-for=userscript_tab]")[0].selected) {
$(".w-icon.w-icon-script").click();
}
// Make UR Comments tab active
$("span[title='URCom Settings']").click();
}
}
} else {
// Reset the id if a ur is not open so we can set the tab for the same ur
UrCommentLasturID = "";
// Switch tab back
if (options.AutoSwitchToURCommentsTab) {
// Verify that we had found a tab
if (PreviousTab !== null) {
$(PreviousTab).click(); // Click back on the previous tab
$('#sidebar div.tab-content').scrollTop( PreviousTabPosition ); // Set scroll pos
// Clear out the previous tab holder
PreviousTab = null;
PreviousTabPosition = null;
}
}
}
}
function URCLoadUpdateRequestsEvents() {
window.HideUR = "stopped";
//from Cardyin 5/26/2016
W.model.mapUpdateRequests.on("objectschanged", urcUREvent_onObjectsAdded('mapUpdateRequests objectschanged')); // needed
W.model.updateRequestSessions.on("objectsadded", urcUREvent_onObjectsAdded('updateRequestSessions objectsadded')); // needed
W.map.events.register("moveend", null, urcUREvent_onObjectsAdded('moveend')); //needed
W.map.events.register("zoomend", null, urcUREvent_onObjectsAdded('zoomend')); //needed
setTimeout(urcUREvent_onObjectsAdded('pageload'), 500);
}
function createSettingsTab() {
applyCss();
// -- Set up the tab for the script
wmeSDK.Sidebar.registerScriptTab().then(({ tabLabel, tabPane }) => {
console.log("[URCom] Register settings tab");
tabLabel.innerHTML = '<img src="' + UrCommentsIcon + '" height="16px" title="URCom" alt="URCom"/> URCom';
tabLabel.title = 'URCom Settings';
tabPane.innerHTML = '<div id="sidepanel-Comments"></div>';
scriptContentPane = $('#sidepanel-Comments');
init();
});
}
function init() {
// Add the content to the comments tab
const tabs = $('<wz-tabs fixed="true"></wz-tabs>');
const textTab = $('<wz-tab is-active label="' + translate("tabs.comments") + '" tooltip="' + translate("tabs.comments") + '"></wz-tab>');
const textTabContent = $('<div id="sidepanel-URComments-list"></div>')
textTab.append(textTabContent);
const settingsTab = $('<wz-tab label="' + translate("tabs.settings") + '" tooltip="' + translate("tabs.settings") + '"></wz-tab>');
const settingsTabContent = $('<div id="sidepanel-URComments-settings"></div>')
settingsTab.append(settingsTabContent);
tabs.append(textTab);
tabs.append(settingsTab);
scriptContentPane.append(tabs);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////
////// Draw Options
//////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
addCommentTexts(textTabContent);
addOptions(settingsTabContent);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////
////// Launch background task(s)
//////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Start looking for opened UR's window
setTimeout(lookForOpenedUR, 1000);
setTimeout(URCLoadUpdateRequestsEvents, 0);
$('#sidepanel-Comments').closest('section').css('padding', '0px');
}
function startCode() {
if ($("#user-tabs").length && InitReady) {
createSettingsTab();
} else {
setTimeout(startCode, 2000);
}
}
async function initDatabase() {
const request = window.indexedDB.open("URCom", 2);
request.onerror = (event) => {
console.error("[URCom] Why didn't you allow my web app to use IndexedDB?!");
};
request.onupgradeneeded = (event) => {
console.log(event);
const db = event.target.result;
if (event.newVersion >= 1 && event.oldVersion < 1) {
const customListStore = db.createObjectStore("custom_lists", { keyPath: "name" });
customListStore.transaction.oncomplete = (event) => {
console.log("[URCom] Created list store");
}
}
if (event.newVersion >= 2 && event.oldVersion < 2) {
const dataStore = db.createObjectStore("data-store", { keyPath: "id" })
dataStore.transaction.oncomplete = (event) => {
console.log("[URCom] Created data store");
}
}
}
request.onsuccess = (event) => {
console.log("[URCom] DB ready");
DB = event.target.result;
};
while (!DB) {
await sleep(10);
}
if ("openDatabase" in window) {
try {
let created = false;
const oldDb = openDatabase(
"URCom", // actual database name. Opens existing or creates.
"1", // version number. *Must* be correct.
"Database to store custom URCom data", //
10 * 1024 * 1024, // Size of the DB
() => {
created = true;
}
);
if (!created) {
console.log("[URCom] Migrating");
await migrateDb(oldDb);
console.log("[URCom] Migration over");
}
} catch (e) {}
}
}
unsafeWindow.SDK_INITIALIZED.then(async () => {
// initialize the sdk with your script id and script name
wmeSDK = getWmeSdk({scriptId: "urcom", scriptName: "UR Comments"});
await URComments_init();
})