From 2fb64772f4ca05453bdc9e1ed304aacac245c81c Mon Sep 17 00:00:00 2001 From: Thomas Rudin Date: Sun, 21 Apr 2019 21:51:43 +0200 Subject: [PATCH] improved search --- server/static/css/custom.css | 8 +-- server/static/js/LayerManager.js | 31 +++++++++++- server/static/js/main.js | 15 +----- server/static/js/search/SearchInput.js | 25 +++++++--- server/static/js/search/SearchMenu.js | 12 ++++- server/static/js/search/SearchResult.js | 21 +++++++- server/static/js/search/SearchService.js | 62 +++++++++++++----------- server/static/js/search/SearchStore.js | 2 + 8 files changed, 120 insertions(+), 56 deletions(-) diff --git a/server/static/css/custom.css b/server/static/css/custom.css index 20f2577..f376691 100644 --- a/server/static/css/custom.css +++ b/server/static/css/custom.css @@ -18,9 +18,9 @@ body { #search-menu { position: absolute; - top: 20%; - bottom: 20%; - left: 20%; - right: 20%; + top: 5%; + bottom: 5%; + left: 5%; + right: 5%; z-index: 99999; } diff --git a/server/static/js/LayerManager.js b/server/static/js/LayerManager.js index 91756ec..5557944 100644 --- a/server/static/js/LayerManager.js +++ b/server/static/js/LayerManager.js @@ -1,18 +1,47 @@ /* exported LayerManager */ +/* globals RealtimeTileLayer: true */ -function LayerManager(layers, map){ +function LayerManager(wsChannel, layers, map){ this.listeners = []; this.currentLayer = layers[0]; this.layers = layers; + this.map = map; + this.layerObjects = {}; var self = this; + //All layers + layers.forEach(function(layer){ + var tileLayer = new RealtimeTileLayer(wsChannel, layer.id, map); + self.layerObjects[layer.name] = tileLayer; + }); + map.on('baselayerchange', function (e) { self.setLayerId(e.layer.layerId); }); + //current layer + var currentLayer = this.getCurrentLayer(); + this.layerObjects[currentLayer.name].addTo(map); } +LayerManager.prototype.switchLayer = function(layerId){ + var self = this; + Object.keys(this.layerObjects).forEach(function(key){ + var layerObj = self.layerObjects[key]; + if (self.map.hasLayer(layerObj)){ + self.map.removeLayer(layerObj); + } + }); + + Object.keys(this.layerObjects).forEach(function(key){ + var layerObj = self.layerObjects[key]; + if (layerObj.layerId == layerId){ + self.map.addLayer(layerObj); + } + }); +}; + LayerManager.prototype.setLayerId = function(layerId){ var self = this; this.layers.forEach(function(layer){ diff --git a/server/static/js/main.js b/server/static/js/main.js index 1d53331..b670e09 100644 --- a/server/static/js/main.js +++ b/server/static/js/main.js @@ -15,22 +15,11 @@ api.getConfig().then(function(cfg){ map.attributionControl.addAttribution('Minetest Mapserver'); - var layers = {}; var overlays = {}; - window.layerMgr = new LayerManager(cfg.layers, map); + window.layerMgr = new LayerManager(wsChannel, cfg.layers, map); layerMgr.setLayerId( Hashroute.getLayerId() ); - //All layers - cfg.layers.forEach(function(layer){ - var tileLayer = new RealtimeTileLayer(wsChannel, layer.id, map); - layers[layer.name] = tileLayer; - }); - - //current layer - var currentLayer = layerMgr.getCurrentLayer(); - layers[currentLayer.name].addTo(map); - //All overlays Overlaysetup(cfg, map, overlays, wsChannel, layerMgr); @@ -43,7 +32,7 @@ api.getConfig().then(function(cfg){ } //layer control - L.control.layers(layers, overlays, { position: "topright" }).addTo(map); + L.control.layers(layerMgr.layerObjects, overlays, { position: "topright" }).addTo(map); Hashroute.setup(map, layerMgr); diff --git a/server/static/js/search/SearchInput.js b/server/static/js/search/SearchInput.js index 8a1817b..adaebd8 100644 --- a/server/static/js/search/SearchInput.js +++ b/server/static/js/search/SearchInput.js @@ -5,21 +5,32 @@ var SearchInput = { view: function(){ function handleInput(e){ - SearchService.search(e.target.value); + SearchStore.query = e.target.value; + } + + function handleKeyDown(e){ + if (e.keyCode == 13){ + SearchService.search(); + } + } + + function handleDoSearch(){ + SearchService.search(); } return m("div", { class: "input-group mb-3" }, [ - m("div", { class: "input-group-prepend" }, [ - m("span", { class: "input-group-text" }, [ - m("i", { class: "fa fa-search"}) - ]) - ]), m("input[type=text]", { placeholder: "Search", class: "form-control", oninput: handleInput, + onkeydown: handleKeyDown, value: SearchStore.query - }) + }), + m("div", { class: "input-group-append", onclick: handleDoSearch }, [ + m("span", { class: "input-group-text" }, [ + m("i", { class: "fa fa-search"}) + ]) + ]) ]); } }; diff --git a/server/static/js/search/SearchMenu.js b/server/static/js/search/SearchMenu.js index a493832..f1da9d9 100644 --- a/server/static/js/search/SearchMenu.js +++ b/server/static/js/search/SearchMenu.js @@ -8,7 +8,7 @@ var SearchMenu = { var style = {}; - if (!SearchStore.query) { + if (!SearchStore.show) { style.display = "none"; } @@ -16,13 +16,21 @@ var SearchMenu = { SearchService.clear(); } + function getContent(){ + if (SearchStore.busy){ + return m("div", m("i", { class: "fa fa-spinner"})); + } else { + return m(SearchResult, { map: vnode.attrs.map }); + } + } + return m("div", { class: "card", id: "search-menu", style: style }, [ m("div", { class: "card-header" }, [ m("i", { class: "fa fa-search"}), "Search", m("i", { class: "fa fa-times float-right", onclick: close }), ]), - m("div", { class: "card-body", style: {overflow: "auto"} }, m(SearchResult, { map: vnode.attrs.map })) + m("div", { class: "card-body", style: {overflow: "auto"} }, getContent()) ]); } }; diff --git a/server/static/js/search/SearchResult.js b/server/static/js/search/SearchResult.js index 48223a7..d7da451 100644 --- a/server/static/js/search/SearchResult.js +++ b/server/static/js/search/SearchResult.js @@ -12,7 +12,6 @@ var SearchResult = { } function getPos(obj){ - var layer = layerMgr.getLayerByY(obj.y); var text = obj.x + "/" + obj.y + "/" + obj.z; return m("span", {class:"badge badge-success"}, text); @@ -24,6 +23,21 @@ var SearchResult = { var description = obj.type; var type = obj.type; + if (obj.type == "train"){ + description = [ + m("span", obj.attributes.station), + " ", + m("span", {class:"badge badge-info"}, obj.attributes.line) + ]; + + type = m("i", { class: "fa fa-subway" }); + } + + if (obj.type == "travelnet"){ + description = m("span", obj.attributes.station_name); + type = m("img", { src: "pics/travelnet_inv.png" }); + } + if (obj.type == "poi"){ description = m("span", obj.attributes.name); type = m("img", { src: "css/images/marker-icon.png" }); @@ -50,7 +64,12 @@ var SearchResult = { } function onclick(){ + var layer = layerMgr.getLayerByY(obj.y); + + layerMgr.switchLayer(layer.id); + map.setView([obj.z, obj.x], 12); + SearchStore.show = false; } return m("tr", {"class": row_classes}, [ diff --git a/server/static/js/search/SearchService.js b/server/static/js/search/SearchService.js index 18f8e14..7cf61e8 100644 --- a/server/static/js/search/SearchService.js +++ b/server/static/js/search/SearchService.js @@ -3,49 +3,55 @@ var SearchService = { - search: function(q){ - SearchStore.query = q; - + search: function(){ + SearchStore.show = true; this.fetchData(); }, - fetchData: debounce(function(){ + fetchData: function(){ SearchStore.result = []; if (!SearchStore.query){ return; } - function searchFor(q){ - q.pos1 = { x:-2048, y:-2048, z:-2048 }; - q.pos2 = { x:2048, y:2048, z:2048 }; - return api.getMapObjects(q); + SearchStore.busy = true; + + function searchFor(type, key, valuelike){ + return api.getMapObjects({ + pos1: { x:-2048, y:-2048, z:-2048 }, + pos2: { x:2048, y:2048, z:2048 }, + type: type, + attributelike: { + key: key, + value: "%" + valuelike +"%" + } + }); } - var shop_prom = searchFor({ - type: "shop", - attributelike: { - key: "out_item", - value: "%" + SearchStore.query + "%" - } + var prom_list = []; + + prom_list.push(searchFor("shop", "out_item", SearchStore.query)); + prom_list.push(searchFor("poi", "name", SearchStore.query)); + prom_list.push(searchFor("train", "station", SearchStore.query)); + prom_list.push(searchFor("travelnet", "station_name", SearchStore.query)); + + Promise.all(prom_list) + .then(function(results){ + + var arr = []; + results.forEach(function(r) { + arr = arr.concat(r); + }); + + SearchStore.result = arr; + SearchStore.busy = false; }); - var poi_prom = searchFor({ - type: "poi", - attributelike: { - key: "name", - value: "%" + SearchStore.query + "%" - } - }); - - Promise.all([shop_prom, poi_prom]).then(function(results){ - SearchStore.result = results[1].concat(results[0]); - }); - - }, 400), + }, clear: function(){ - SearchStore.query = ""; SearchStore.result = []; + SearchStore.show = false; } }; diff --git a/server/static/js/search/SearchStore.js b/server/static/js/search/SearchStore.js index 656d4e6..397abb0 100644 --- a/server/static/js/search/SearchStore.js +++ b/server/static/js/search/SearchStore.js @@ -2,5 +2,7 @@ var SearchStore = { query: "", + show: false, + busy: false, result: [] };