WME Place Interface Enhancements

Enhancements to various Place interfaces

目前為 2017-01-09 提交的版本,檢視 最新版本

// ==UserScript==
// @name         WME Place Interface Enhancements
// @namespace    https://greasyfork.org/users/30701-justins83-waze
// @version      0.3.0
// @description  Enhancements to various Place interfaces
// @include      https://www.waze.com/editor/*
// @include      https://www.waze.com/*/editor/*
// @include      https://beta.waze.com/*
// @exclude      https://www.waze.com/user/editor*
// @author       JustinS83
// @grant        none
// @require      https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @license      GPLv3
// ==/UserScript==

(function() {
    'use strict';

    var settings = {};

    // Your code here...
    function bootstrap(tries) {
        tries = tries || 1;

        if (window.W &&
            window.W.map &&
            window.W.model &&
            $) {
            init();
        } else if (tries < 1000) {
            setTimeout(function () {bootstrap(tries++);}, 200);
        }
    }

    bootstrap();

    function init(){
        var $section = $("<div>", {style:"padding:8px 16px", id:"WMEPIESettings"});
        $section.html([
            '<h4><b>WME Place Interface Enhancements</b></h4>',
            '<div class="controls-container" id="divAreaPlaceSizeControls">',
            '<div id="divShowAreaPlaceSize" class="controls-container"><input type="checkbox" id="_cbShowAreaPlaceSize" class="pieSettingsCheckbox" /><label for="_cbShowAreaPlaceSize">Show area Place size</label></div>',
            '<div id="divShowAreaPlaceSizeImperial"class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeImperial" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeImperial"> Show imperial </label></div>',
            '<div id="divShowAreaPlaceSizeMetric" class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeMetric" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeMetric"> Show metric</label></div>',
            '</div>',
            '<div class="controls-container" id="divShowLockButtonsRPP"><input type="checkbox" id="_cbShowLockButtonsRPP" class="pieSettingsCheckbox" /><label for="_cbShowLockButtonsRPP">Show lock buttons for RPPs</label></div>',
            '<div class="controls-container" id="divPlaceMenuCustomization">',
            '<b>Place Menu Customization</b></br>',
            buildItemOption(1),
            buildItemOption(2),
            buildItemOption(3),
            buildItemOption(4),
            buildItemOption(5),
            buildItemOption(6),
            buildItemOption(7),
            buildItemOption(8),
            buildItemOption(9),
            buildItemOption(10),
            buildItemOption(11),
            '</div>'

        ].join(' '));
        new WazeWrap.Interface.Tab('PIE', $section.html(), init2);
    }

    function buildNewPlaceList(){
        /*<div class="drawing-controls">
        <span class="drawing-control polygon secondary-control" title="Place (area)"></span>
        <span class="drawing-control main-control point" title="Place (point)"></span>
        </div>
        $('#pieItem1')[0].options[$('#pieItem1')[0].selectedIndex].innerHTML //get selected option text
        */
    }

    function init2(){
        //First load settings
        loadSettings();
        //Second set up event handlers
        $('#_cbShowAreaPlaceSize').change(function() {
            if(this.checked) {
                attachPlaceSizeHandlers();
                updatePlaceSizeDisplay();
                $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
                $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            }
            else
            {
                removePlaceSizeHandlers();
                $('#AreaSize').remove();
                $('#_cbShowAreaPlaceSizeImperial')[0].disabled = true;
                $('#_cbShowAreaPlaceSizeMetric')[0].disabled = true;
            }
        });

        $('#_cbShowLockButtonsRPP').change(function() {
            if(this.checked) {
                attachRPPLockButtonHandlers();
            }
            else
            {
                $('#RPPOptionPlaceLockButtonsContainer').remove();
                W.selectionManager.events.unregister("selectionchanged", null, addLockButtons);
                W.model.actionManager.events.unregister("afterundoaction",null, addLockButtons);
                W.model.actionManager.events.unregister("afterclearactions",null, addLockButtons);
                W.model.actionManager.events.unregister("afteraction",null, addLockButtons);
            }
        });

        //Third load settings to interface
        setChecked('_cbShowAreaPlaceSize', settings.ShowAreaPlaceSize);
        setChecked('_cbShowAreaPlaceSizeImperial', settings.ShowAreaPlaceSizeImperial);
        setChecked('_cbShowAreaPlaceSizeMetric', settings.ShowAreaPlaceSizeMetric);
        setChecked('_cbShowLockButtonsRPP', settings.ShowLockButtonsRPP);
        if(settings.ShowAreaPlaceSize){
            $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
            $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            attachPlaceSizeHandlers();
        }

        if(settings.ShowLockButtonsRPP)
            attachRPPLockButtonHandlers();

        $('.pieSettingsCheckbox').change(function() {
             var settingName = $(this)[0].id.substr(3);
            settings[settingName] = this.checked;
            saveSettings();
        });

        //Whenever a Place item is changed, read the settings and save to localStorage
        $('[id^="pieItem"]').change(function(){
            for(i=0;i<11;i++){
                settings.NewPlacesList[i] = $('#pieItem'+(i+1))[0].value;
            }
            saveSettings();
        });

        //Load settings into Place Customization list options
        for(i=0; i<11;i++)
            $('#pieItem'+(i+1))[0].value = settings.NewPlacesList[i];
    }

    function buildItemOption(itemNumber){
        var $section = $("<div>", {style:"padding:8px 16px", id:"piePlaceCat" + itemNumber});
        $section.html([
            'Item ',
            itemNumber,
            buildItemList(itemNumber),
            '</br>'
            ].join(' '));

        return $section.html();
    }

    function buildItemList(itemNumber){
        /*var yourSelect = document.getElementById( "your-select-id" );
        alert( yourSelect.options[ yourSelect.selectedIndex ].value )*/
        
        var $places = $("<div>");
        $places.html([
            '<select id="pieItem' + itemNumber + '">',
            '<option value="CAR_SERVICES" style="font-weight:bold;">Car Services</option>',
            '<option value="GAS_STATION">Gas Station</option>',
            '<option value="GARAGE_AUTOMOTIVE_SHOP">Garage / Automotive Shop</option>',
            '<option value="CAR_WASH">Car Wash</option>',
            '<option value="CHARGING_STATION">Charging Station</option>',
            '<option value="TRANSPORTATION" style="font-weight:bold;">Transportation</option>',
            '<option value="AIRPORT">Airport</option>',
            '<option value="BUS_STATION">Bus Station</option>',
            '<option value="FERRY_PIER">Ferry / Pier</option>',
            '<option value="SEAPORT_MARINA_HARBOR">Seaport / Marina / Harbor</option>',
            '<option value="SUBWAY_STATION">Subway Station</option>',
            '<option value="TRAIN_STATION">Train Station</option>',
            '<option value="BRIDGE">Bridge</option>',
            '<option value="TUNNEL">Tunnel</option>',
            '<option value="TAXI_STATION">Taxi Station</option>',
            '<option value="JUNCTION_INTERCHANGE">Junction / Interchange</option>',
            '<option value="PROFESSIONAL_AND_PUBLIC" style="font-weight:bold;">Professional and public</option>',
            '<option value="COLLEGE_UNIVERSITY">College / University</option>',
            '<option value="SCHOOL">School</option>',
            '<option value="CONVENTIONS_EVENT_CENTER">Conventions / Event Center</option>',
            '<option value="GOVERNMENT">Government</option>',
            '<option value="LIBRARY">Library</option>',
            '<option value="CITY_HALL">City Hall</option>',
            '<option value="ORGANIZATION_OR_ASSOCIATION">Organization or Association</option>',
            '<option value="COURTHOUSE">Courthouse</option>',
            '<option value="CEMETERY">Cemetery</option>',
            '<option value="FIRE_DEPARTMENT">Fire Department</option>',
            '<option value="POLICE_STATION">Police Station</option>',
            '<option value="MILITARY">Military</option>',
            '<option value="HOSPITAL_MEDICAL_CARE">Hospital / Medical Care</option>',
            '<option value="OFFICES">Offices</option>',
            '<option value="POST_OFFICE">Post Office</option>',
            '<option value="RELIGIOUS_CENTER">Religious Center</option>',
            '<option value="KINDERGARDEN">Kindergarden</option>',
            '<option value="FACTORY_INDUSTRIAL">Factory / Industrial</option>',
            '<option value="EMBASSY_CONSULATE">Embassy / Consulate</option>',
            '<option value="INFORMATION_POINT">Information Point</option>',
            '<option value="EMERGENCY_SHELTER">Emergency Shelter</option>',
            '<option value="SHOPPING_AND_SERVICES" style="font-weight:bold;">Shopping and services</option>',
            '<option value="ARTS_AND_CRAFTS">Arts & Crafts</option>',
            '<option value="BANK_FINANCIAL">Bank / Financial</option>',
            '<option value="SPORTING_GOODS">Sporting Goods</option>',
            '<option value="BOOKSTORE">Bookstore</option>',
            '<option value="PHOTOGRAPHY">Photography</option>',
            '<option value="CAR_DEALERSHIP">Car Dealership</option>',
            '<option value="FASHION_AND_CLOTHING">Fashion and Clothing</option>',
            '<option value="CONVENIENCE_STORE">Convenience Store</option>',
            '<option value="PERSONAL_CARE">Personal Care</option>',
            '<option value="DEPARTMENT_STORE">Department Store</option>',
            '<option value="PHARMACY">Pharmacy</option>',
            '<option value="ELECTRONICS">Electronics</option>',
            '<option value="FLOWERS">Flowers</option>',
            '<option value="FURNITURE_HOME_STORE">Furniture / Home Store</option>',
            '<option value="GIFTS">Gifts</option>',
            '<option value="GYM_FITNESS">Gym / Fitness</option>',
            '<option value="SWIMMING_POOL">Swimming Pool</option>',
            '<option value="HARDWARE_STORE">Hardware Store</option>',
            '<option value="MARKET">Market</option>',
            '<option value="SUPERMARKET_GROCERY">Supermarket / Grocery</option>',
            '<option value="JEWELRY">Jewelry</option>',
            '<option value="LAUNDRY_DRY_CLEAN">Laundry / Dry Clean</option>',
            '<option value="SHOPPING_CENTER">Shopping Center</option>',
            '<option value="MUSIC_STORE">Music Store</option>',
            '<option value="PET_STORE_VETERINARIAN_SERVICES">Pet Store / Veterinarian Services</option>',
            '<option value="TOY_STORE">Toy Store</option>',
            '<option value="TRAVEL_AGENCY">Travel Agency</option>',
            '<option value="ATM">ATM</option>',
            '<option value="CURRENCY_EXCHANGE">Currency Exchange</option>',
            '<option value="CAR_RENTAL">Car Rental</option>',
            '<option value="FOOD_AND_DRINK" style="font-weight:bold;">Food and Drink</option>',
            '<option value="RESTAURANT">Restaurant</option>',
            '<option value="BAKERY">Bakery</option>',
            '<option value="DESSERT">Dessert</option>',
            '<option value="CAFE">Cafe</option>',
            '<option value="FAST_FOOD">Fast Food</option>',
            '<option value="FOOD_COURT">Food Court</option>',
            '<option value="BAR">Bar</option>',
            '<option value="ICE_CREAM">Ice Cream</option>',
            '<option value="CULTURE_AND_ENTERTAINEMENT" style="font-weight:bold;">Culture & Entertainment</option>',
            '<option value="ART_GALLERY">Art Gallery</option>',
            '<option value="CASINO">Casino</option>',
            '<option value="CLUB">Club</option>',
            '<option value="TOURIST_ATTRACTION_HISTORIC_SITE">Tourist Attraction / History Site</option>',
            '<option value="MOVIE_THEATER">Movie Theater</option>',
            '<option value="MUSEUM">Museum</option>',
            '<option value="MUSIC_VENUE">Music Venue</option>',
            '<option value="PERFORMING_ARTS_VENUE">Performing Arts Venue</option>',
            '<option value="GAME_CLUB">Game Club</option>',
            '<option value="STADIUM_ARENA">Stadium / Arena</option>',
            '<option value="THEME_PARK">Theme Park</option>',
            '<option value="ZOO_AQUARIUM">Zoo / Aquarium</option>',
            '<option value="RACING_TRACK">Racing Track</option>',
            '<option value="THEATER">Theater</option>',
            '<option value="OTHER" style="font-weight:bold;">Other</option>',
            '<option value="CONSTRUCTION_SITE">Construction Site</option>',
            '<option value="LODGING" style="font-weight:bold;">Lodging</option>',
            '<option value="HOTEL">Hotel</option>',
            '<option value="HOSTEL">Hostel</option>',
            '<option value="CAMPING_TRAILER_PARK">Camping / Trailer Park</option>',
            '<option value="COTTAGE_CABIN">Cottage / Cabin</option>',
            '<option value="BED_AND_BREAKFAST">Bed & Breakfast</option>',
            '<option value="OUTDOORS" style="font-weight:bold;">Outdoors</option>',
            '<option value="PARK">Park</option>',
            '<option value="PLAYGROUND">Playground</option>',
            '<option value="BEACH">Beach</option>',
            '<option value="SPORTS_COURT">Sports Court</option>',
            '<option value="GOLF_COURSE">Golf Course</option>',
            '<option value="PLAZA">Plaza</option>',
            '<option value="PROMENADE">Promenade</option>',
            '<option value="POOL">Pool</option>',
            '<option value="SCENIC_LOOKOUT_VIEWPOINT">Scenic Lookout / Viewpoint</option>',
            '<option value="SKI_AREA">Ski Area</option>',
            '<option value="NATURAL_FEATURES" style="font-weight:bold;">Natural Features</option>',
            '<option value="ISLAND">Island</option>',
            '<option value="SEA_LAKE_POOL">Sea / Lake / Pool</option>',
            '<option value="RIVER_STREAM">River / Stream</option>',
            '<option value="FOREST_GROVE">Forest / Grove</option>',
            '<option value="FARM">Farm</option>',
            '<option value="CANAL">Canal</option>',
            '<option value="SWAMP_MARSH">Swamp / Marsh</option>',
            '<option value="DAM">Dam</option>',
            '<option value="PARKING_LOT" style="font-weight:bold;">Parking Lot</option>',
            '<option value="RESIDENCE_HOME" style="font-weight:bold;">Residential</option>',
            '</select>'
            ].join(' '));

        return $places.html();
    }

    function attachRPPLockButtonHandlers(){
        $('#RPPOptionPlaceLockButtonsContainer').remove();
        W.selectionManager.events.register("selectionchanged", null, addLockButtons);
        W.model.actionManager.events.register("afterundoaction",null, addLockButtons);
        W.model.actionManager.events.register("afterclearactions",null, addLockButtons);
        W.model.actionManager.events.register("afteraction",null, addLockButtons);
    }

    function attachPlaceSizeHandlers(){
        W.selectionManager.events.register("selectionchanged", null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afteraction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afterundoaction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afterclearactions",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("noActions",null, noActions);
        updatePlaceSizeDisplay();
    }

    function removePlaceSizeHandlers(){
        W.selectionManager.events.unregister("selectionchanged", null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afteraction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afterundoaction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afterclearactions",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("noActions",null, noActions);
    }

    function isChecked(checkboxId) {
        return $('#' + checkboxId).is(':checked');
    }

    function setChecked(checkboxId, checked) {
        $('#' + checkboxId).prop('checked', checked);
    }

    function noActions(){
        setTimeout(updatePlaceSizeDisplay, 100 ); //have to put in a delay for when the user uses undo to clear all actions - WME updates on top of my changes otherwise.
    }

    function updatePlaceSizeDisplay(){
        var count = W.selectionManager.selectedItems.length;
        var metersArea = 0;
        var bold = false;
        if(count === 1){
           var venue = W.selectionManager.selectedItems[0];
           var isArea = venue.geometry.toString().match(/^POLYGON/);
           //var isPoint = venue.geometry.toString().match(/^POINT/);

            if(venue.model.type === "venue" && isArea){
                if($('#AreaSize'))
                    $('#AreaSize').remove();
                metersArea = W.selectionManager.selectedItems[0].model.geometry.getGeodesicArea(W.map.getProjectionObject());

                if(metersArea > 0 && isArea){
                    var ftArea = Math.round(metersArea * 10.76391 *100)/100;

                    var list = $('#landmark-edit-general > ul')[0];
                    var newList = document.createElement("UL");
                    newList.id = "AreaSize";

                    var newItem = document.createElement("LI");
                    if(isChecked("_cbShowAreaPlaceSizeMetric")){
                        newItem.innerHTML = "Area: " + metersArea.toFixed(2) + " m<sup>2</sup>";
                        newList.append(newItem);
                    }

                    if(isChecked("_cbShowAreaPlaceSizeImperial")){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "Area: " + ftArea.toFixed(2) + " ft<sup>2</sup>";
                        newList.append(newItem);
                    }
                    if(metersArea < 500){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "<span style='color:red; font-weight:bold;'>Places smaller than 500 m<sup>2</sup>/5382 ft<sup>2</sup> will not show in the client</span>";
                        newList.append(newItem);
                    }
                    list.before(newList);

                    $('#AreaSize').addClass("list-unstyled");
                    $('#AreaSize').addClass("additional-attributes");
                }
            }
        }
    }

    function loadSettings() {
        var loadedSettings = $.parseJSON(localStorage.getItem("WMEPIE_Settings"));
        var defaultSettings = {
            ShowAreaPlaceSize: false,
            ShowAreaPlaceSizeImperial: false,
            ShowAreaPlaceSizeMetric: false,
            ShowLockButtonsRPP: true,
            NewPlacesList: W.Config.venues.categories.clone()
        };
        settings = loadedSettings ? loadedSettings : defaultSettings;
        for (var prop in defaultSettings) {
            if (!settings.hasOwnProperty(prop))
                settings[prop] = defaultSettings[prop];
        }

        if(settings.ShowAreaPlaceSizeImperial === false && settings.ShowAreaPlaceSizeMetric === false)
            if(Waze.prefs.attributes.isImperial)
                settings.ShowAreaPlaceSizeImperial = true;
            else
                settings.ShowAreaPlaceSizeMetric = true;
    }

     function saveSettings() {
        if (localStorage) {
            var localsettings = {
                ShowAreaPlaceSize: settings.ShowAreaPlaceSize,
                ShowAreaPlaceSizeImperial: settings.ShowAreaPlaceSizeImperial,
                ShowAreaPlaceSizeMetric: settings.ShowAreaPlaceSizeMetric,
                ShowLockButtonsRPP: settings.ShowLockButtonsRPP,
                NewPlacesList: settings.NewPlacesList
            };

            localStorage.setItem("WMEPIE_Settings", JSON.stringify(localsettings));
        }
    }

    //Using the same display for lock buttons as ClickSaver (with permission from MapoMatic) - thanks MoM!
    function addLockButtons() {
        if(W.selectionManager.selectedItems.length > 0){
            var item = W.selectionManager.selectedItems[0];
            var isRPP = (item.model.type === "venue" && item.model.attributes.residential === true);

            if(isRPP){
                console.log("adding!!!");
                var attr = item.model.attributes;
                var autoRank = attr.rank;
                var manualRank = attr.lockRank;
                var firstManualRank = manualRank;
                var userRank = WazeWrap.User.Rank() - 1;
                var maxAutoRank = autoRank;
                var disabled = false;

                var $div = $('#RPPOptionPlaceLockButtonsContainer');
                $div.remove();
                $div = $('<div>',{id:'RPPOptionPlaceLockButtonsContainer',style:'margin-bottom:5px;'});
                $div.append('<label class="control-label">Lock</label>');
                var btnInfos = [];

                for(var iBtn=0;iBtn<=6;iBtn++){btnInfos.push({r:iBtn,val:iBtn});}
                btnInfos.forEach(function(btnInfo){
                    var selected = (btnInfo.val === manualRank);
                    disabled = userRank < btnInfo.val;
                    if (btnInfo.val !== 6) {
                        $div.append(
                            $('<div>', {
                                class:'btn btn-lh' + (selected ? ' btn-lh-selected':'') + (btnInfo.r < 6 & (userRank < btnInfo.r || disabled) ? ' disabled' : '')
                            })
                            .text(btnInfo.hasOwnProperty('title') ? btnInfo.title : btnInfo.r + 1)
                            .data('val',btnInfo.hasOwnProperty('val') ? btnInfo.val : btnInfo.r + 1)
                            .hover(function() {})
                            .click(function() {
                                if((userRank >= $(this).data('val')) && (btnInfo.r < 6)) {
                                    W.model.actionManager.add(new UpdateObject(item.model,{lockRank:($(this).data('val'))}));
                                    addLockButtons();
                                }
                            })
                        );
                    }
                });
                $('#landmark-edit-general > div').after($div);
            }
        }
    }

    function listPlaces(){
        var category = "";
        for(i=0; i<W.Config.venues.categories.length; i++){
            category = W.Config.venues.categories[i];
            console.log(category + " Main");
            var subCategories = W.Config.venues.subcategories[category];
            for(var j=0; j<subCategories.length;j++){
                console.log(subCategories[j]);
            }
        }
    }
})();