From 73986b2992dc7827df9d34eecaecc99280ea05d3 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Thu, 15 Jun 2023 14:08:43 +0300 Subject: [PATCH] Search: add search tips --- Web/Models/Repositories/Users.php | 5 ++- Web/Presenters/SearchPresenter.php | 52 +++++++++++++++++++++++ Web/Presenters/templates/@layout.xml | 10 ++++- Web/routes.yml | 2 + Web/static/css/main.css | 47 +++++++++++++++++++++ Web/static/js/openvk.cls.js | 62 +++++++++++++++++++++++++++- locales/en.strings | 2 + locales/ru.strings | 2 + 8 files changed, 178 insertions(+), 4 deletions(-) diff --git a/Web/Models/Repositories/Users.php b/Web/Models/Repositories/Users.php index 0eec3306..6c165aa3 100644 --- a/Web/Models/Repositories/Users.php +++ b/Web/Models/Repositories/Users.php @@ -58,7 +58,7 @@ class Users $nnparamsCount = 0; foreach($pars as $paramName => $paramValue) - if($paramName != "before" && $paramName != "after" && $paramName != "gender" && $paramName != "maritalstatus" && $paramName != "politViews") + if($paramName != "before" && $paramName != "after" && $paramName != "gender" && $paramName != "maritalstatus" && $paramName != "politViews" && $paramName != "doNotSearchMe") $paramValue != NULL ? $notNullParams += ["$paramName" => "%$paramValue%"] : NULL; else $paramValue != NULL ? $notNullParams += ["$paramName" => "$paramValue"] : NULL; @@ -125,6 +125,9 @@ class Users case "gender": $result->where("sex ?", $paramValue); break; + case "doNotSearchMe": + $result->where("id !=", $paramValue); + break; } } } diff --git a/Web/Presenters/SearchPresenter.php b/Web/Presenters/SearchPresenter.php index fadf9954..48d7b8c8 100644 --- a/Web/Presenters/SearchPresenter.php +++ b/Web/Presenters/SearchPresenter.php @@ -100,4 +100,56 @@ final class SearchPresenter extends OpenVKPresenter $this->template->type = $type; $this->template->page = $page; } + + function renderFastSearch() + { + $this->assertUserLoggedIn(); + $this->willExecuteWriteAction(); + + if($_SERVER["REQUEST_METHOD"] === "POST") { + + $query = $this->queryParam("query") ?? ""; + + if($query == "" || strlen($query) < 3) + $this->returnJson([ + "error" => "type something longer" + ]); + + $type = $this->queryParam("type") ?? "users"; + + $isUsers = $type == "users"; + $repo = $isUsers ? (new Users) : (new Clubs); + $sort = $isUsers ? "rating DESC" : "id ASC"; + + $res = $repo->find($query, ["doNotSearchMe" => $this->user->id], $sort); + + $results = array_slice(iterator_to_array($res), 0, 5); + + $count = sizeof($results); + + $arr = [ + "count" => $count, + "items" => [] + ]; + + if(sizeof($results) < 1) { + $this->returnJson(["err" => "No results"]); + } + + foreach($results as $res) { + + $arr["items"][] = [ + "id" => $res->getId(), + "name" => $isUsers ? $res->getCanonicalName() : $res->getName(), + "avatar" => $res->getAvatarUrl(), + "url" => $res->getUrl(), + "description" => ovk_proc_strtr($res->getDescription() ?? "...", 40) + ]; + } + + $this->returnJson($arr); + } else { + $this->returnJson(["err" => "or"]); + } + } } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 7bb7e194..cd23d47a 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -93,8 +93,8 @@ {if !$atSearch}
- - +
+ {else}
diff --git a/Web/routes.yml b/Web/routes.yml index d1a0e7ae..9c214a50 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -251,6 +251,8 @@ routes: handler: "Search->index" - url: "/search/content" handler: "ContentSearch->index" + - url: "/fastSearch" + handler: "Search->fastSearch" - url: "/notes{num}" handler: "Notes->list" - url: "/note{num}_{num}" diff --git a/Web/static/css/main.css b/Web/static/css/main.css index ac8de971..d7a7b3d5 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2487,3 +2487,50 @@ a.poll-retract-vote { .page_content.overscrolled div[class$="_big_block"] { width: 100%; } + +.searchTips +{ + position: absolute; + background: white; + padding-left: 6px; + padding-right: 6px; + padding-bottom: 6px; + border: 1px solid #C0CAD5; + border-top: 0px; + font-size: 15px; + width: fit-content; + z-index: 666666; + margin-top: -1px; +} + +.searchTips td +{ + color: black; + padding: 3px; + font-weight: lighter; + position:relative; +} + +.searchTips td .desq +{ + margin-top: -9px; +} + +.restip td a:hover +{ + color: black; + font-weight: lighter; + text-decoration: none; +} + +.searchTips .restip +{ + padding-right: 10px; + cursor: pointer; + user-select: none; +} + +.searchTips .restip:hover +{ + background: rgb(236, 235, 235); +} diff --git a/Web/static/js/openvk.cls.js b/Web/static/js/openvk.cls.js index 31b7aa5d..11ddb1a4 100644 --- a/Web/static/js/openvk.cls.js +++ b/Web/static/js/openvk.cls.js @@ -1,4 +1,6 @@  +const { json } = require("stream/consumers"); + function expand_wall_textarea(id) { var el = document.getElementById('post-buttons'+id); var wi = document.getElementById('wall-post-input'+id); @@ -590,9 +592,11 @@ async function decreaseSearch() { // чтобы люди успели выбрать что искать и поиск не скрывался сразу await new Promise(r => setTimeout(r, 4000)); + // console.log("search decreased") - if(document.activeElement !== searchInput) + if(document.activeElement !== searchInput && document.activeElement !== typer) { + srcht.setAttribute("hidden", "hidden") document.getElementById("searchInput").style.background = "url('/assets/packages/static/openvk/img/search_icon.png') no-repeat 3px 4px"; document.getElementById("searchInput").style.backgroundColor = "#fff"; document.getElementById("searchInput").style.paddingLeft = "18px"; @@ -642,6 +646,62 @@ function resetSearch() } } +async function checkSearchTips() +{ + let query = searchInput.value; + + await new Promise(r => setTimeout(r, 500)); + + let type = typer.value; + let smt = type == "users" || type == "groups"; + if(query.length > 3 && query == searchInput.value && smt) { + srcht.removeAttribute("hidden") + let etype = type == "groups" ? "clubs" : "users" + + let xhr = new XMLHttpRequest() + xhr.open("POST", "/fastSearch?query="+query+"&type="+etype) + + xhr.onloadstart = () => { + srchrr.innerHTML = `` + } + + xhr.onloadend = async () => { + let results; + + try { + results = JSON.parse(xhr.responseText) + } catch { + srchrr.innerHTML = "Rate limits" + } + + if(results["items"] != null) { + srchrr.innerHTML = "" + + for(const el of results["items"]) { + srchrr.insertAdjacentHTML("beforeend", ` + + + + + +

${el.name}

+

${el.description}

+ + + `) + + } + } else { + srchrr.innerHTML = tr("no_results") + } + } + + xhr.send() + } else { + //srcht.setAttribute("hidden", "hidden") + } +} + $(document).on("scroll", () => { if($(document).scrollTop() > $(".sidebar").height() + 50) { $(".floating_sidebar")[0].classList.add("show"); diff --git a/locales/en.strings b/locales/en.strings index 16e37928..a9f57c9e 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -1507,6 +1507,8 @@ "closed_group_post" = "This is a post from private group"; "deleted_target_comment" = "This comment belongs to deleted post"; +"no_results" = "No results"; + /* Mobile */ "mobile_friends" = "Friends"; "mobile_photos" = "Photos"; diff --git a/locales/ru.strings b/locales/ru.strings index 1b4cb632..eb8ffd41 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -1400,6 +1400,8 @@ "closed_group_post" = "Эта запись из закрытой группы"; "deleted_target_comment" = "Этот комментарий принадлежит к удалённой записи"; +"no_results" = "Результатов нет"; + /* Mobile */ "mobile_friends" = "Друзья"; "mobile_photos" = "Фотографии";