diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 306baf60..e01446e6 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -206,6 +206,9 @@ final class Wall extends VKAPIRequestHandler if($post->isDeactivationMessage()) $post_temp_obj->final_post = 1; + if($post->getGeo()) + $post_temp_obj->geo = $post->getVkApiGeo(); + $items[] = $post_temp_obj; if ($from_id > 0) @@ -321,14 +324,10 @@ final class Wall extends VKAPIRequestHandler } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { $attachments[] = $attachment->getApiStructure($this->getUser()); } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { - if(VKAPI_DECL_VER === '4.100') { - $attachments[] = $attachment->toVkApiStruct(); - } else { - $attachments[] = [ - 'type' => 'note', - 'note' => $attachment->toVkApiStruct() - ]; - } + $attachments[] = [ + 'type' => 'note', + 'note' => $attachment->toVkApiStruct() + ]; } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { $attachments[] = [ "type" => "audio", @@ -419,6 +418,9 @@ final class Wall extends VKAPIRequestHandler if($post->isDeactivationMessage()) $post_temp_obj->final_post = 1; + if($post->getGeo()) + $post_temp_obj->geo = $post->getVkApiGeo(); + $items[] = $post_temp_obj; if ($from_id > 0) @@ -493,7 +495,11 @@ final class Wall extends VKAPIRequestHandler ]; } - function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0): object + function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0, + float $lat = NULL, + float $long = NULL, + string $place_name = '' + ): object { $this->requireUser(); $this->willExecuteWriteAction(); @@ -584,44 +590,6 @@ final class Wall extends VKAPIRequestHandler if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) $this->fail(100, "Required parameter 'message' missing."); - $geo = NULL; - - if ($latitude && $longitude) { - $latitude = number_format($latitude, 8, ".", ''); - $longitude = number_format($longitude, 8, ".", ''); - - if ((!$latitude || !$longitude) || ($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180)) { - $this->fail(100, "Invalid latitude or longitude"); - } - - $geo = array( - "name" => null, - "lat" => $latitude, - "lng" => $longitude, - ); - - if (strlen(trim($geo_name))) { - $geo["name"] = $geo_name; - } else { - $info = file_get_contents("https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2", false, stream_context_create([ - 'http' => [ - 'method' => 'GET', - 'header' => implode("\r\n", [ - 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2', - "Referer: https://$_SERVER[SERVER_NAME]/" - ]) - ] - ])); - - if ($info) { - $info = json_decode($info, true, JSON_UNESCAPED_UNICODE); - if (key_exists("place_id", $info)) { - $geo["name"] = $info["name"] ?? $info["display_name"]; - } - } - } - } - try { $post = new Post; $post->setOwner($this->getUser()->getId()); @@ -637,6 +605,45 @@ final class Wall extends VKAPIRequestHandler } catch(\Throwable) {} } + /*$info = file_get_contents("https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2", false, stream_context_create([ + 'http' => [ + 'method' => 'GET', + 'header' => implode("\r\n", [ + 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/22.0.1216.0 Safari/537.2', + "Referer: https://$_SERVER[SERVER_NAME]/" + ]) + ] + ])); + + if ($info) { + $info = json_decode($info, true, JSON_UNESCAPED_UNICODE); + if (key_exists("place_id", $info)) { + $geo["name"] = $info["name"] ?? $info["display_name"]; + } + }*/ + if($lat && $long) { + if(($lat > 90 || $lat < -90) || ($long > 180 || $long < -180)) { + $this->fail(-785, 'Invalid geo info'); + } + + $latitude = number_format((float) $lat, 8, ".", ''); + $longitude = number_format((float) $long, 8, ".", ''); + + $res = [ + 'lat' => $latitude, + 'lng' => $longitude + ]; + if($place_name && mb_strlen($place_name) > 0) { + $res['name'] = $place_name; + } else { + $res['name'] = 'Geopoint'; + } + + $post->setGeo(json_encode($res)); + $post->setGeo_Lat($latitude); + $post->setGeo_Lon($longitude); + } + if($should_be_suggested) $post->setSuggested(1); @@ -1167,6 +1174,52 @@ final class Wall extends VKAPIRequestHandler return 1; } + function getNearby(int $owner_id, int $post_id) + { + $this->requireUser(); + + $post = (new PostsRepo)->getPostById($owner_id, $post_id); + if(!$post || $post->isDeleted()) + $this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined"); + + if(!$post->canBeViewedBy($this->getUser())) + $this->fail(15, "Access denied"); + + $lat = $post->getLat(); + $lon = $post->getLon(); + + if(!$lat || !$lon) + $this->fail(-97, "Post doesn't contains geo"); + + $query = file_get_contents(__DIR__ . "/../../Web/Models/sql/get-nearest-posts.tsql"); + $_posts = \Chandler\Database\DatabaseConnection::i()->getContext()->query($query, $lat, $lon, $post->getId())->fetchAll(); + $posts = []; + + foreach($_posts as $post) { + $distance = $post["distance"]; + $post = (new PostsRepo)->get($post["id"]); + if (!$post || $post->isDeleted() || !$post->canBeViewedBy($this->getUser())) continue; + + $owner = $post->getOwner(); + $preview = mb_substr($post->getText(), 0, 50) . (strlen($post->getText()) > 50 ? "..." : ""); + $posts[] = [ + "message" => strlen($preview) > 0 ? $preview : "(нет текста)", + "url" => "/wall" . $post->getPrettyId(), + "created" => $post->getPublicationTime()->html(), + "owner" => [ + "domain" => $owner->getURL(), + "photo_50" => $owner->getAvatarURL(), + "name" => $owner->getCanonicalName(), + "verified" => $owner->isVerified(), + ], + "geo" => $post->getGeo(), + "distance" => $distance + ]; + } + + return $posts; + } + private function getApiPhoto($attachment) { return [ "type" => "photo", diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 9b207023..f3f8e1f7 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -472,6 +472,14 @@ class Post extends Postable { return (float) $this->getRecord()->geo_lon ?? NULL; } + + function getVkApiGeo(): object + { + return (object) [ + 'type' => 'point', + 'coordinates' => $this->getLat() . ',' . $this->getLon(), + ]; + } use Traits\TRichText; } diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index ca3dba89..3790e5a3 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -309,37 +309,20 @@ final class WallPresenter extends OpenVKPresenter $this->flashFail("err", tr("failed_to_publish_post"), "Poll format invalid"); } - if(empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1 && !$poll) - $note = NULL; - - if(!is_null($this->postParam("note")) && $this->postParam("note") != "none") { - $note = (new Notes)->get((int)$this->postParam("note")); - - if(!$note || $note->isDeleted() || $note->getOwner()->getId() != $this->user->id) { - $this->flashFail("err", tr("error"), tr("error_attaching_note")); - } - - if($note->getOwner()->getPrivacySetting("notes.read") < 1) { - $this->flashFail("err", " "); - } - } - $geo = NULL; - if (!is_null($this->postParam("geo")) && $this->postParam("geo") != "none") { + if (!is_null($this->postParam("geo")) && $this->postParam("geo") != "") { $geo = json_decode($this->postParam("geo"), true, JSON_UNESCAPED_UNICODE); - if (!$geo["lat"] || !$geo["lng"] || !$geo["name"]) { - $this->flashFail("err", tr("error"), tr("error_geolocation")); - } - - $latitude = number_format((float) $geo["lat"], 8, ".", ''); - $longitude = number_format((float) $geo["lng"], 8, ".", ''); - if ($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180) { - $this->flashFail("err", tr("error"), "Invalid latitude or longitude"); + if($geo["lat"] && $geo["lng"] && $geo["name"]) { + $latitude = number_format((float) $geo["lat"], 8, ".", ''); + $longitude = number_format((float) $geo["lng"], 8, ".", ''); + if($latitude > 90 || $latitude < -90 || $longitude > 180 || $longitude < -180) { + $this->flashFail("err", tr("error"), "Invalid latitude or longitude"); + } } } - if(empty($this->postParam("text")) && !$photo && !$video && !$poll && !$note && !$geo) + if(empty($this->postParam("text")) && sizeof($horizontal_attachments) < 1 && sizeof($vertical_attachments) < 1 && !$poll) $this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_empty_or_too_big")); $should_be_suggested = $wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2; @@ -712,49 +695,4 @@ final class WallPresenter extends OpenVKPresenter $this->template->page = $page; $this->template->perPage = OPENVK_DEFAULT_PER_PAGE; } - - function renderNearest(int $wall, int $post_id): void - { - if ($_SERVER["REQUEST_METHOD"] !== "POST") $this->notFound(); - $this->assertUserLoggedIn(); - - $post = $this->posts->getPostById($wall, $post_id); - if(!$post) - $this->notFound(); - - $lat = $post->getLat(); - $lon = $post->getLon(); - - if (!$lat || !$lon) - $this->returnJson(["success" => false, "error" => tr("error_no_geotag")]); - - $query = file_get_contents(__DIR__ . "/../Models/sql/get-nearest-posts.tsql"); - $_posts = DatabaseConnection::i()->getContext()->query($query, $lat, $lon, $post->getId())->fetchAll(); - $posts = []; - foreach ($_posts as $post) { - $distance = $post["distance"]; - $post = (new Posts)->get($post["id"]); - if (!$post || $post->isDeleted()) continue; - - $owner = $post->getOwner(); - - $preview = mb_substr($post->getText(), 0, 50) . (strlen($post->getText()) > 50 ? "..." : ""); - $posts[] = [ - "preview" => strlen($preview) > 0 ? $preview : "(нет текста)", - "url" => "/wall" . $post->getPrettyId(), - "time" => $post->getPublicationTime()->html(), - "owner" => [ - "url" => $owner->getURL(), - "avatar_url" => $owner->getAvatarURL(), - "name" => $owner->getCanonicalName(), - "verified" => $owner->isVerified(), - "writes" => ($owner instanceof User) ? ($owner->isFemale() ? tr("post_writes_f") : tr("post_writes_m")) : tr("post_writes_m") - ], - "geo" => $post->getGeo(), - "distance" => $distance - ]; - } - - $this->returnJson(["success" => true, "posts" => $posts, "need_count" => count($posts) === 25]); - } } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index b7d84b96..811548cd 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -404,6 +404,11 @@ {script "js/al_feed.js"} {/ifset} + {script "js/node_modules/leaflet/dist/leaflet.js"} + {script "js/node_modules/leaflet-control-geocoder/dist/Control.Geocoder.js"} + {css "js/node_modules/leaflet/dist/leaflet.css"} + {css "js/node_modules/leaflet-control-geocoder/dist/Control.Geocoder.css"} + diff --git a/Web/Presenters/templates/components/post/microblogpost.xml b/Web/Presenters/templates/components/post/microblogpost.xml index ba4a8667..b39b8239 100644 --- a/Web/Presenters/templates/components/post/microblogpost.xml +++ b/Web/Presenters/templates/components/post/microblogpost.xml @@ -92,10 +92,12 @@ -
- - - {_geotag}: {$post->getGeo()->name ?? tr("admin_open")} +
+ + + + + {$post->getGeo()->name ?? tr("admin_open")}
diff --git a/Web/Presenters/templates/components/post/oldpost.xml b/Web/Presenters/templates/components/post/oldpost.xml index 8e647b7f..3612aa1d 100644 --- a/Web/Presenters/templates/components/post/oldpost.xml +++ b/Web/Presenters/templates/components/post/oldpost.xml @@ -90,10 +90,12 @@
-
-
-
- {_geotag}: {$post->getGeo()->name ?? tr("admin_open")} +
+
+ + + + {$post->getGeo()->name ?? tr("admin_open")}
diff --git a/Web/Presenters/templates/components/textArea.xml b/Web/Presenters/templates/components/textArea.xml index 6c5a8e21..bd2291c3 100644 --- a/Web/Presenters/templates/components/textArea.xml +++ b/Web/Presenters/templates/components/textArea.xml @@ -60,7 +60,7 @@ - +
@@ -98,9 +98,9 @@ {_poll} - + - Гео-метка + {_geo_place} diff --git a/Web/routes.yml b/Web/routes.yml index 4157acb7..7fd0cfe7 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -145,8 +145,6 @@ routes: handler: "Wall->decline" - url: "/{text}/{num}_{num}/likes" handler: "Wall->likers" - - url: "/wall{num}_{num}/nearest" - handler: "Wall->nearest" - url: "/blob_{text}/{?path}.{text}" handler: "Blob->file" placeholders: diff --git a/Web/static/css/main.css b/Web/static/css/main.css index 8f465432..6d03daa5 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -851,6 +851,11 @@ h4 { margin-bottom: 2px; } +.post-geo { + margin: 1px 0px; + padding: 0 4px; +} + .post-signature span { color: grey; } @@ -3911,3 +3916,9 @@ hr { top: 3px; font-size: 15px; } + +.map_svg_icon { + display: inline-block; + margin-bottom: -2px; + fill: #7d7d7d; +} diff --git a/Web/static/img/geo.svg b/Web/static/img/geo.svg deleted file mode 100755 index 6357697d..00000000 --- a/Web/static/img/geo.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 0706b11a..d7f36f9d 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -2588,153 +2588,183 @@ async function changeStatus() { document.status_popup_form.submit.disabled = false; } -async function initGeo(tid) { - MessageBox(tr("attach_geotag"), "
", ["Прикрепить", tr("cancel")], [(function () { - let marker = { - lat: currentMarker._latlng.lat, - lng: currentMarker._latlng.lng, - name: $(`#geo-name-input-${tid}`).val() ? $(`#geo-name-input-${tid}`).val() : $(`#geo-name-${tid}`).text() - }; - $(`#post-buttons${tid} #geo`).val(JSON.stringify(marker)); - $(`#post-buttons${tid} .post-has-geo`).text(`${tr("geotag")}: ${marker.name}`); - $(`#post-buttons${tid} .post-has-geo`).show(); - }), Function.noop]); +const tplMapIcon = ` + +` - const element = document.getElementById('osm-map'); - element.style = 'height: 600px;'; +u(document).on('click', "#__geoAttacher", async (e) => { + const form = u(e.target).closest('#write') + const buttons = form.find('.post-buttons') - let markerLayers = L.layerGroup(); + let current_coords = [54.51331, 36.2732] + let currentMarker = null + const getCoords = async () => { + const pos = await new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition((position) => { + resolve([position.coords.latitude, position.coords.longitude]) + }, () => { + resolve([54.51331, 36.2732]) + }, + { + enableHighAccuracy: true, + timeout: 5000, + maximumAge: 0, + }) + }) - let map = L.map(element, { - center: [55.322978, 38.673362], + return pos + } + + current_coords = await getCoords() + + const geo_msg = new CMessageBox({ + title: tr('attach_geotag'), + body: `
`, + buttons: [tr('attach'), tr('cancel')], + callbacks: [() => { + if(!currentMarker) { + return + } + + const geo_name = $(`#geo-name`).html() + if(geo_name == '') { + return + } + + const marker = { + lat: currentMarker._latlng.lat, + lng: currentMarker._latlng.lng, + name: escapeHtml(geo_name) + } + buttons.find(`input[name='geo']`).nodes[0].value = JSON.stringify(marker) + buttons.find(`.post-has-geo`).html(` + ${tplMapIcon} + ${escapeHtml(geo_name)} +
+ `) + }, () => {}] + }) + + // by n1rwana + const markerLayers = L.layerGroup() + const map = L.map(u('#osm-map').nodes[0], { + center: current_coords, zoom: 10, attributionControl: false, width: 800 - }); - let currentMarker = null; - markerLayers.addTo(map); + }) + markerLayers.addTo(map) - map.on('click', (e) => { - let lat = e.latlng.lat; - let lng = e.latlng.lng; + map.on('click', async (e) => { + const lat = e.latlng.lat + const lng = e.latlng.lng - if (currentMarker) map.removeLayer(currentMarker); + if(currentMarker) map.removeLayer(currentMarker); - $.get({ - url: `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=jsonv2`, - success: (response) => { - markerLayers.clearLayers(); + const marker_fetch_req = await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=jsonv2`) + const marker_fetch = await marker_fetch_req.json() - currentMarker = L.marker([lat, lng]).addTo(map); + markerLayers.clearLayers() + currentMarker = L.marker([lat, lng]).addTo(map) - let name = response?.name ?? response?.display_name ?? tr("geotag"); - let content = `${name}`; - content += ``; + let marker_name = marker_fetch && marker_fetch.display_name ? short_geo_name(marker_fetch.address) : tr('geotag') + const content = `${marker_name}`; - currentMarker.bindPopup(content).openPopup(); - markerLayers.addLayer(currentMarker); - } - }) - }); + currentMarker.bindPopup(content).openPopup() + markerLayers.addLayer(currentMarker) + }) const geocoderControl = L.Control.geocoder({ defaultMarkGeocode: false, - }).addTo(map); + }).addTo(map) geocoderControl.on('markgeocode', function (e) { - console.log(e); - let lat = e.geocode.properties.lat; - let lng = e.geocode.properties.lon; - let name = (e.geocode.properties?.name ?? e.geocode.properties.display_name); + console.log(e.geocode.properties) + const lat = e.geocode.properties.lat + const lng = e.geocode.properties.lon + const name = e.geocode.properties?.display_name ? short_geo_name(e.geocode.properties?.address) : tr('geotag') - if (currentMarker) map.removeLayer(currentMarker); + if(currentMarker) map.removeLayer(currentMarker) - currentMarker = L.marker([lat, lng]).addTo(map); - currentMarker.bindPopup(name).openPopup(); + currentMarker = L.marker([lat, lng]).addTo(map) + currentMarker.bindPopup(`${escapeHtml(name)}`).openPopup() - console.log(`${tr("latitude")}: ${lat}, ${tr("longitude")}: ${lng}`); - console.log(`${tr("name_of_the_place")}: ${name}`); - - let marker = { + marker = { lat: lat, lng: lng, name: name }; map.setView([lat, lng], 15); - }); + }) L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '©
OpenStreetMap contributors' - }).addTo(map); + }).addTo(map) - $(".ovk-diag-cont").width('50%'); - setTimeout(function(){ map.invalidateSize()}, 100); -} + geo_msg.getNode().nodes[0].style = 'width:90%' + setTimeout(function(){ map.invalidateSize()}, 100) +}) + +u(document).on('click', '.post-has-geo #small_remove_button', (e) => { + const form = u(e.target).closest('#write') + const geo = form.find('.post-has-geo') + geo.remove() + form.find(`input[name='geo']`).nodes[0].value = '' +}) function openGeo(data, owner_id, virtual_id) { - MessageBox(tr("geotag"), "
", [tr("nearest_posts"), "OK"], [(function () { - getNearPosts(owner_id, virtual_id); - }), Function.noop]); + MessageBox(tr("geotag"), "
", [tr("nearest_posts"), tr("close")], [async () => { + const posts = await OVKAPI.call('wall.getNearby', {owner_id: owner_id, post_id: virtual_id}) + openNearPosts(posts) + }, Function.noop]); let element = document.getElementById('osm-map'); - element.style = 'height: 600px;'; + element.style = 'height: 80vh;'; let map = L.map(element, {attributionControl: false}); let target = L.latLng(data.lat, data.lng); map.setView(target, 15); let marker = L.marker(target).addTo(map); - marker.bindPopup(data.name ?? tr("geotag")).openPopup(); + marker.bindPopup(escapeHtml(data.name ?? tr("geotag"))).openPopup(); L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); - $(".ovk-diag-cont").width('50%'); + $(".ovk-diag-cont").width('80%'); setTimeout(function(){ map.invalidateSize()}, 100); } -function getNearPosts(owner_id, virtual_id) { - $.ajax({ - type: "POST", - url: `/wall${owner_id}_${virtual_id}/nearest`, - success: (response) => { - if (response.success) { - openNearPosts(response); - } else { - MessageBox(tr("error"), `${tr("error_segmentation")}: ${(response?.error ?? "Unknown error")}`, ["OK"], [Function.noop]); - } - } - }); -} - -function getPostPopup(post) { - return ` +function tplPost(post) { + return ` @@ -2745,14 +2775,14 @@ function getPostPopup(post) { } function openNearPosts(posts) { - if (posts.posts.length > 0) { + if (posts.length > 0) { let MsgTxt = "
"; - MsgTxt += "

Показаны последние 25 постов за месяц
"; + MsgTxt += `

${tr('shown_last_nearest_posts', 25)}
`; - MessageBox("Ближайшие посты", MsgTxt, ["OK"], [Function.noop]); + MessageBox(tr('nearest_posts'), MsgTxt, ["OK"], [Function.noop]); let element = document.getElementById('osm-map'); - element.style = 'height: 600px;'; + element.style = 'height: 80vh;'; let markerLayers = L.layerGroup(); let map = L.map(element, {attributionControl: false}); @@ -2762,11 +2792,11 @@ function openNearPosts(posts) { let markersBounds = []; let coords = []; - posts.posts.forEach((post) => { + posts.forEach((post) => { if (coords.includes(`${post.geo.lat} ${post.geo.lng}`)) { markerLayers.getLayers().forEach((marker) => { if (marker.getLatLng().lat === post.geo.lat && marker.getLatLng().lng === post.geo.lng) { - let content = marker.getPopup()._content += getPostPopup(post); + let content = marker.getPopup()._content += tplPost(post); if (!content.startsWith(`
`)) content = `
${content}`; @@ -2775,7 +2805,7 @@ function openNearPosts(posts) { }); } else { let marker = L.marker(L.latLng(post.geo.lat, post.geo.lng)).addTo(map); - marker.bindPopup(getPostPopup(post)); + marker.bindPopup(tplPost(post)); markerLayers.addLayer(marker); markersBounds.push(marker.getLatLng()); } @@ -2790,11 +2820,11 @@ function openNearPosts(posts) { attribution: '© OpenStreetMap contributors' }).addTo(map); - $(".ovk-diag-cont").width('50%'); + $(".ovk-diag-cont").width('80%'); setTimeout(function () { map.invalidateSize() }, 100); } else { - MessageBox("Ближайшие посты", "
Нет ближайших постов :(
", ["OK"], [Function.noop]); + MessageBox(tr('nearest_posts'), `
${tr('no_nearest_posts')}
`, ["OK"], [Function.noop]); } } diff --git a/Web/static/js/router.js b/Web/static/js/router.js index d72249c5..28d8c2ad 100644 --- a/Web/static/js/router.js +++ b/Web/static/js/router.js @@ -164,6 +164,10 @@ window.router = new class { return false } + if(url.indexOf('#close') != -1) { + return false + } + return true } @@ -234,6 +238,11 @@ window.router = new class { } u(document).on('click', 'a', async (e) => { + if(e.defaultPrevented) { + console.log('AJAX | Skipping because default is prevented') + return + } + const target = u(e.target).closest('a') const dom_url = target.attr('href') const id = target.attr('id') @@ -289,6 +298,10 @@ u(document).on('click', 'a', async (e) => { }) u(document).on('submit', 'form', async (e) => { + if(e.defaultPrevented) { + return + } + if(u('#ajloader').hasClass('shown')) { e.preventDefault() return diff --git a/Web/static/js/utils.js b/Web/static/js/utils.js index 56614757..efaaf05e 100644 --- a/Web/static/js/utils.js +++ b/Web/static/js/utils.js @@ -284,3 +284,30 @@ function collect_attachments_node(target) }) vertical_input.nodes[0].value = vertical_array.join(',') } + +function short_geo_name(address_osm) +{ + let final_arr = [] + if(address_osm.country) { + final_arr.push(address_osm.country) + } + if(address_osm.state) { + final_arr.push(address_osm.state) + } + if(address_osm.state_district) { + final_arr.push(address_osm.state_district) + } + if(address_osm.city) { + final_arr.push(address_osm.city) + } else if(address_osm.town) { + final_arr.push(address_osm.town) + } + if(address_osm.city_district) { + final_arr.push(address_osm.city_district) + } + if(address_osm.road) { + final_arr.push(address_osm.road) + } + + return escapeHtml(final_arr.join(', ')) +} diff --git a/locales/en.strings b/locales/en.strings index 4434a615..ed085737 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -282,11 +282,14 @@ "liked_by_x_people_other" = "Liked by $1 users"; "liked_by_x_people_zero" = "Nobody liked"; +"geo_place" = "Place"; "geotag" = "Geotag"; "nearest_posts" = "Nearest posts"; "Latitude" = "Latitude"; "longitude" = "Longitude"; -"name_of_the_place" = "Name of the place"; +"name_of_the_place" = "Place's name"; +"no_nearest_posts" = "No nearby posts"; +"shown_last_nearest_posts" = "Showing last $1 posts per month"; /* Friends */ diff --git a/locales/ru.strings b/locales/ru.strings index ce4fc973..ad0c8375 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -260,11 +260,15 @@ "liked_by_x_people_many" = "Понравилось $1 людям"; "liked_by_x_people_other" = "Понравилось $1 людям"; "liked_by_x_people_zero" = "Никому не понравилось"; -"geotag" = "Геоточка"; + +"geo_place" = "Место"; +"geotag" = "Геолокация"; "nearest_posts" = "Ближайшие посты"; "Latitude" = "Широта"; "longitude" = "Долгота"; "name_of_the_place" = "Название места"; +"no_nearest_posts" = "Нет ближайших постов"; +"shown_last_nearest_posts" = "Показаны последние $1 постов за месяц"; /* Friends */
- - + + -
-
- ${post.preview} +
+
+ ${escapeHtml(post.message)}
-
${tr("geotag")}: ${post.geo.name ?? tr("admin_open")}
+
+ ${tplMapIcon} + ${escapeHtml(post.geo.name)} +