Search: add search tips

This commit is contained in:
lalka2016 2023-06-15 14:08:43 +03:00
parent 0d167ac18b
commit 73986b2992
8 changed files with 178 additions and 4 deletions

View file

@ -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;
}
}
}

View file

@ -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"]);
}
}
}

View file

@ -93,8 +93,8 @@
{if !$atSearch}
<form action="/search" method="get" id="searcher" style="position:relative;">
<input id="searchInput" onfocus="expandSearch()" onblur="decreaseSearch()" class="sr" type="search" name="query" placeholder="{_header_search}" style="height: 20px;background: url('/assets/packages/static/openvk/img/search_icon.png') no-repeat 3px 4px; background-color: #fff; padding-left: 18px;width: 120px;" title="{_header_search} [Alt+Shift+F]" accesskey="f" />
<select name="type" class="whatFind" style="display:none;top: 0px;">
<input autocomplete="off" id="searchInput" oninput="checkSearchTips()" onfocus="expandSearch()" onblur="decreaseSearch()" class="sr" type="search" name="query" placeholder="{_header_search}" style="height: 20px;background: url('/assets/packages/static/openvk/img/search_icon.png') no-repeat 3px 4px; background-color: #fff; padding-left: 18px;width: 120px;" title="{_header_search} [Alt+Shift+F]" accesskey="f" />
<select onchange="checkSearchTips()" id="typer" name="type" class="whatFind" style="display:none;top: 0px;">
<option value="users">{_s_by_people}</option>
<option value="groups">{_s_by_groups}</option>
<option value="posts">{_s_by_posts}</option>
@ -103,6 +103,12 @@
<option value="apps">{_s_by_apps}</option>
</select>
</form>
<div class="searchTips" id="srcht" hidden>
<table style="border:none;border-spacing: 0;">
<tbody id="srchrr">
</tbody>
</table>
</div>
{else}
<form action="/search" method="get" id="searcher" style="margin-top: -1px;position:relative;">
<input id="searchInput" value="{$_GET['query'] ?? ''}" type="search" class="sr" name="query" placeholder="{_header_search}" style="height: 20px; background-color: #fff; padding-left: 6px;width: 555px;" title="{_header_search} [Alt+Shift+F]" accesskey="f" />

View file

@ -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}"

View file

@ -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);
}

View file

@ -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 = `<img id="loader" src="/assets/packages/static/openvk/img/loading_mini.gif">`
}
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", `
<tr class="restip" onmousedown="if (event.which === 2) { window.open('${el.url}', '_blank'); } else {location.href='${el.url}'}">
<td>
<img src="${el.avatar}" width="30">
</td>
<td valign="top">
<p class="nameq" style="margin-top: -2px;">${el.name}</p>
<p class="desq">${el.description}</p>
</td>
</tr>
`)
}
} 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");

View file

@ -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";

View file

@ -1400,6 +1400,8 @@
"closed_group_post" = "Эта запись из закрытой группы";
"deleted_target_comment" = "Этот комментарий принадлежит к удалённой записи";
"no_results" = "Результатов нет";
/* Mobile */
"mobile_friends" = "Друзья";
"mobile_photos" = "Фотографии";