results highlight, midnight changes, player insear

This commit is contained in:
mrilyew 2024-10-20 23:13:14 +03:00
parent b7a332df3a
commit 2ebeab3f94
14 changed files with 190 additions and 72 deletions

View file

@ -1321,10 +1321,15 @@ class User extends RowModel
return true;
}
function isClosed()
function isClosed(): bool
{
return (bool) $this->getProfileType();
}
function isHideFromGlobalFeedEnabled(): bool
{
return $this->isClosed();
}
function getRealId()
{

View file

@ -62,7 +62,7 @@ class Users
switch($order['type']) {
case 'id':
case 'reg_date':
$order_str = 'since ' . ($order['invert'] ? 'ASC' : 'DESC');
$order_str = 'id ' . ($order['invert'] ? 'ASC' : 'DESC');
break;
case 'rating':
$order_str = 'rating DESC';

View file

@ -146,7 +146,7 @@ final class AudioPresenter extends OpenVKPresenter
$isAjax = $this->postParam("ajax", false) == 1;
if(!is_null($this->queryParam("gid")) && !is_null($this->queryParam("playlist"))) {
exit('ты тупой еблан');
$this->flashFail("err", tr("forbidden"), tr("not_enough_permissions_comment"), null, $isAjax);
}
if(!is_null($this->queryParam("gid"))) {
@ -689,6 +689,28 @@ final class AudioPresenter extends OpenVKPresenter
$audios = $stream->page($page, 10);
$audiosCount = $stream->size();
break;
case "classic_search_context":
$data = json_decode($this->postParam("context_entity"), true);
$params = [];
$order = [
"type" => $data['order'] ?? 'id',
"invert" => (int)$data['invert'] == 1 ? true : false
];
if($data['genre'] && $data['genre'] != 'any')
$params['genre'] = $data['genre'];
if($data['only_performers'] && (int)$data['only_performers'] == 1)
$params['only_performers'] = '1';
if($data['with_lyrics'] && (int)$data['with_lyrics'] == 1)
$params['with_lyrics'] = '1';
$stream = $this->audios->find($data['query'], $params, $order);
$audios = $stream->page($page, 10);
$audiosCount = $stream->size();
break;
}
$pagesCount = ceil($audiosCount / $perPage);

View file

@ -107,6 +107,7 @@ final class SearchPresenter extends OpenVKPresenter
$count = $results->size();
$this->template->order = $order;
$this->template->invert = $invert;
$this->template->data = $this->template->iterator = iterator_to_array($iterator);
$this->template->count = $count;
$this->template->section = $section;

View file

@ -1,4 +1,4 @@
<div class="bigPlayer">
<div n:class="bigPlayer, $tidy ? tidy">
<audio class="audio" />
<div class="paddingLayer">
<div class="playButtons">

View file

@ -15,6 +15,11 @@
<div class="wrap2">
<div class="wrap1">
<div class="page_wrap">
{if $section == 'audios' && $count > 1}
{include "../Audio/bigplayer.xml", tidy => true}
<input type="hidden" name="bigplayer_context" data-type="classic_search_context" data-entity='{"order":"{$order}","query":"{$query}","invert":{$invert ? 1 : 0},"only_performers":{$_REQUEST['only_performers'] ? 1 : 0},"genre":"{$_REQUEST['genre']}","with_lyrics":"{$_REQUEST['with_lyrics'] ? 1 : 0}"}' data-page="{$page}">
{/if}
<div class='summaryBar summaryBarFlex padding'>
<div class='summary'>
<b>{tr("results", $count)} {tr("showing_x_y", $page, $count)}</b>
@ -24,7 +29,7 @@
</div>
<div class='page_wrap_content' id='search_page'>
<div class='page_wrap_content_main'>
<div n:class='page_wrap_content_main, $section == "audios" ? audios_padding'>
{if $count > 0}
{if $section === 'users'}
<div class='search_content def_row_content' n:foreach="$data as $dat">
@ -118,6 +123,10 @@
</tbody>
</table>
</div>
<script n:if='$count > 0 && !empty($query)'>
highlightText({$query}, '.page_wrap_content_main', ['text'])
</script>
{elseif $section === 'groups'}
<div class='search_content def_row_content' n:foreach="$data as $dat">
<table>
@ -150,7 +159,7 @@
<td>
<span class="nobold">{_description}:</span>
</td>
<td>
<td data-highlight='_clubDesc'>
{$dat->getDescription() ?? '(' . tr("none") . ')'}
</td>
</tr>
@ -169,6 +178,10 @@
</tbody>
</table>
</div>
<script n:if='$count > 0 && !empty($query)'>
highlightText({$query}, '.page_wrap_content_main', ['text', "td[data-highlight='_clubDesc']"])
</script>
{elseif $section === 'apps'}
<div class='search_content def_row_content' n:foreach="$data as $dat">
<table>
@ -186,44 +199,64 @@
&nbsp;{$dat->getName()}
</text>
</b>
</a>
<table class="ugc-table">
<tbody>
<tr>
<td>
{$dat->getDescription() ?? '(' . tr("none") . ')'}
</td>
</tr>
</tbody>
</table>
<br/>
</a><br/>
<span style='margin-left: 2px;' data-highlight='_appDesc'>
{$dat->getDescription() ?? '(' . tr("none") . ')'}
</span>
</td>
</tr>
</tbody>
</table>
</div>
<script n:if='$count > 0 && !empty($query)'>
highlightText({$query}, '.page_wrap_content_main', ['text', "span[data-highlight='_appDesc']"])
</script>
{elseif $section === 'posts'}
{* шмалим дурь курим шмаль дуем коку пиво пьём *}
<div class='search_content' n:foreach="$data as $dat">
{include "../components/post.xml", post => $dat, commentSection => true, onWallOf => true}
{if !$dat || $dat->getWallOwner()->isHideFromGlobalFeedEnabled()}
{_closed_group_post}.
{else}
{include "../components/post.xml", post => $dat, commentSection => true, onWallOf => true}
{/if}
</div>
<script n:if='$count > 0 && !empty($query)'>
highlightText({$query}, '.page_wrap_content_main', [".post:not(.comment) > tbody > tr > td > .post-content > .text .really_text"])
</script>
{elseif $section === 'comments'}
<div class='search_content' n:foreach="$data as $dat">
{include "../components/comment.xml", no_reply_button => true, comment => $dat, correctLink => true}
</div>
<script n:if='$count > 0 && !empty($query)'>
highlightText({$query}, '.page_wrap_content_main', [".text .really_text"])
</script>
{elseif $section === 'videos'}
<div class='search_content' n:foreach="$data as $dat">
{include "../components/video.xml", video => $dat}
</div>
</div>
<script n:if='$count > 0 && !empty($query)'>
highlightText({$query}, '.page_wrap_content_main', [".video_name", ".video_description"])
</script>
{elseif $section === 'audios'}
<div class='search_content' n:foreach="$data as $dat">
{include "../Audio/player.xml", audio => $dat}
</div>
<script n:if="$count > 0 && !empty($query) && empty($_REQUEST['only_performers'])">
highlightText({$query}, '.page_wrap_content_main', [".mediaInfo .performer a", ".mediaInfo .title"])
</script>
{elseif $section === 'audios_playlists'}
<div class='search_content' n:foreach="$data as $dat">
{include "../Audio/playlistListView.xml", playlist => $dat}
</div>
<script n:if="$count > 0 && !empty($query) && empty($_REQUEST['only_performers'])">
highlightText({$query}, '.page_wrap_content_main', [".playlistName", ".playlistDesc"])
</script>
{/if}
{else}
{include "../components/content_error.xml", description => tr("no_results_by_this_query")}
@ -231,14 +264,14 @@
</div>
<div class='page_wrap_content_options verticalGrayTabsWrapper'>
<div class="page_wrap_content_options_list verticalGrayTabs with_padding">
<a n:attr="id => $section === 'users' ? 'used'" href="/search?section=users&q={$query}"> {_s_people}</a>
<a n:attr="id => $section === 'groups' ? 'used'" href="/search?section=groups&q={$query}"> {_s_groups}</a>
<a n:attr="id => $section === 'posts' ? 'used'" href="/search?section=posts&q={$query}"> {_s_posts}</a>
<a n:attr="id => $section === 'comments' ? 'used'" href="/search?section=comments&q={$query}"> {_s_comments}</a>
<a n:attr="id => $section === 'videos' ? 'used'" href="/search?section=videos&q={$query}"> {_s_videos}</a>
<a n:attr="id => $section === 'apps' ? 'used'" href="/search?section=apps&q={$query}"> {_s_apps}</a>
<a n:attr="id => $section === 'audios' ? 'used'" href="/search?section=audios&q={$query}"> {_s_audios}</a>
<a n:attr="id => $section === 'audios_playlists' ? 'used'" href="/search?section=audios_playlists&q={$query}">{_s_audios_playlists}</a>
<a n:attr="id => $section === 'users' ? 'used'" href="/search?section=users&q={urlencode($query)}"> {_s_people}</a>
<a n:attr="id => $section === 'groups' ? 'used'" href="/search?section=groups&q={urlencode($query)}"> {_s_groups}</a>
<a n:attr="id => $section === 'posts' ? 'used'" href="/search?section=posts&q={urlencode($query)}"> {_s_posts}</a>
<a n:attr="id => $section === 'comments' ? 'used'" href="/search?section=comments&q={urlencode($query)}"> {_s_comments}</a>
<a n:attr="id => $section === 'videos' ? 'used'" href="/search?section=videos&q={urlencode($query)}"> {_s_videos}</a>
<a n:attr="id => $section === 'apps' ? 'used'" href="/search?section=apps&q={urlencode($query)}"> {_s_apps}</a>
<a n:attr="id => $section === 'audios' ? 'used'" href="/search?section=audios&q={urlencode($query)}"> {_s_audios}</a>
<a n:attr="id => $section === 'audios_playlists' ? 'used'" href="/search?section=audios_playlists&q={urlencode($query)}">{_s_audios_playlists}</a>
</div>
<div class='page_search_options'>

View file

@ -33,7 +33,7 @@
{/block}
{block preview}
<div class="video-preview" id="videoOpen" data-id="{$x->getId()}">
<div class="video-preview" data-id="{$x->getId()}">
<img src="{$x->getThumbnailURL()}"
alt="{$x->getName()}"
style="max-width: 170px; max-height: 127px; margin: auto;" />
@ -41,7 +41,7 @@
{/block}
{block name}
<span id="videoOpen" data-id="{$x->getId()}" style="color:unset;">{$x->getName()}</span>
<span data-id="{$x->getId()}" style="color:unset;">{$x->getName()}</span>
{/block}
{block description}
@ -51,7 +51,7 @@
<span style="color: grey;">{_video_uploaded} {$x->getPublicationTime()}</span><br/>
<span style="color: grey;">{_video_updated} {$x->getEditTime() ?? $x->getPublicationTime()}</span>
<p>
<a href="/video{$x->getPrettyId()}" id="videoOpen" data-id="{$x->getId()}">{_view_video}</a>
<a href="/video{$x->getPrettyId()}" data-id="{$x->getId()}">{_view_video}</a>
{if $x->getCommentsCount() > 0}| <a href="/video{$x->getPrettyId()}#comments">{_comments} ({$x->getCommentsCount()})</a>{/if}
</p>
{/block}

View file

@ -42,17 +42,20 @@
{if !$timeOnly}
&nbsp;|
{if $comment->canBeDeletedBy($thisUser)}
<a href="/comment{$comment->getId()}/delete">{_delete}</a>&nbsp;|
<a href="/comment{$comment->getId()}/delete">{_delete}</a>
{/if}
{if $comment->canBeEditedBy($thisUser)}
<a id="editPost" data-id="{$comment->getId()}">{_edit}</a>&nbsp;|
|
<a id="editPost" data-id="{$comment->getId()}">{_edit}</a>
{/if}
{if !$no_reply_button}
|
<a class="comment-reply">{_reply}</a>
{/if}
{if $thisUser->getId() != $comment->getOwner()->getId()}
{if $thisUser->getId() != $author->getRealId()}
|
{var $canReport = true}
| <a href="javascript:reportComment()">{_report}</a>
<a href="javascript:reportComment()">{_report}</a>
{/if}
<div style="float: right; font-size: .7rem;">
<a class="post-like-button" href="/comment{$comment->getId()}/like?hash={rawurlencode($csrfToken)}">

View file

@ -4,7 +4,7 @@
<tr>
<td valign="top">
<div class="video-preview">
<a href="/video{$video->getPrettyId()}" id="videoOpen" data-id="{$video->getId()}">
<a href="/video{$video->getPrettyId()}" {$videoModal ? "id='videoOpen'" : ''} data-id="{$video->getId()}">
<img src="{$video->getThumbnailURL()}"
style="max-width: 170px; max-height: 127px; margin: auto;" >
</a>
@ -15,18 +15,18 @@
{include infotable, x => $dat}
{else}
<a href="/video{$video->getPrettyId()}">
<b id="videoOpen" data-id="{$video->getId()}">
<b class='video_name' {$videoModal ? "id='videoOpen'" : ''} data-id="{$video->getId()}">
{$video->getName()}
</b>
</a>
<br/>
<p>
<span>{$video->getDescription() ?? ""}</span>
<span class='video_description'>{$video->getDescription() ?? ""}</span>
</p>
<span style="color: grey;">{_video_uploaded} {$video->getPublicationTime()}</span><br/>
<p>
<a href="/video{$video->getPrettyId()}" id="videoOpen" data-id="{$video->getId()}">{_view_video}</a>
<a href="/video{$video->getPrettyId()}" {$videoModal ? "id='videoOpen'" : ''} data-id="{$video->getId()}">{_view_video}</a>
{if $video->getCommentsCount() > 0}| <a href="/video{$video->getPrettyId()}#comments">{_comments} ({$video->getCommentsCount()})</a>{/if}
</p>
{/ifset}

View file

@ -31,6 +31,12 @@
z-index: 1;
}
.bigPlayer.tidy {
width: 100%;
margin-left: unset;
margin-top: unset;
}
.bigPlayer.floating {
position: fixed;
z-index: 199;
@ -177,6 +183,7 @@
text-overflow: ellipsis;
white-space: nowrap;
width: 81%;
height: 13px;
display: inline-block;
}
@ -588,8 +595,6 @@
margin-left: 3px;
width: 11px;
height: 11px;
background: url('/assets/packages/static/openvk/img/explicit.svg');
background-repeat: no-repeat;
}
.explicitMark path {

View file

@ -2675,6 +2675,10 @@ a.poll-retract-vote {
width: 74%;
}
.page_wrap_content_main.audios_padding {
padding: 8px 8px;
}
.page_wrap_content_main .def_row_content {
border-bottom: #ECECEC solid 1px;
padding: 3px 1px;
@ -2747,6 +2751,13 @@ a.poll-retract-vote {
background: #ebebeb;
}
.highlight {
background: #ffea6d;
border-bottom: 1px solid #c7c727;
font-weight: bolder;
padding: 0px 1px;
}
/* Options */
.page_wrap_content .page_search_options {

View file

@ -500,15 +500,35 @@ function escapeHtml(text) {
return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}
function highlightText(selector, searchText) {
const container = u(selector)
let innerHTML = container.html()
const index = innerHTML.indexOf(searchText)
function highlightText(searchText, container_selector, selectors = []) {
const container = u(container_selector)
const regexp = new RegExp(`(${searchText})`, 'gi')
if(index >= 0) {
innerHTML = innerHTML.substring(0, index) + "<span class='highlight'>" + innerHTML.substring(index, index + searchText.length) + "</span>" + innerHTML.substring(index + searchText.length)
container.html(innerHTML)
function highlightNode(node) {
if(node.nodeType == 3) {
let newNode = escapeHtml(node.nodeValue)
newNode = newNode.replace(regexp, (match, ...args) => {
return `<span class='highlight'>${escapeHtml(match)}</span>`
})
const tempDiv = document.createElement('div')
tempDiv.innerHTML = newNode
while(tempDiv.firstChild) {
node.parentNode.insertBefore(tempDiv.firstChild, node)
}
node.parentNode.removeChild(node)
} else if(node.nodeType === 1 && node.tagName !== 'SCRIPT' && node.tagName !== 'BR' && node.tagName !== 'STYLE') {
Array.from(node.childNodes).forEach(highlightNode);
}
}
selectors.forEach(selector => {
elements = container.find(selector)
if(!elements || elements.length < 1) return;
elements.nodes.forEach(highlightNode)
})
}
String.prototype.escapeHtml = function() {

View file

@ -1922,7 +1922,7 @@
"s_any_single" = "любой";
"reset" = "Сброс";
"closed_group_post" = "Эта запись из закрытой группы";
"closed_group_post" = "Запись с закрытой стены";
"deleted_target_comment" = "Этот комментарий принадлежит к удалённой записи";
"no_results" = "Результатов нет";

View file

@ -124,14 +124,13 @@ th,
.tippy-box[data-theme~="vk"],
.poll,
#standaloneCommentBox,
.searchBtn,
.searchList #used,
.searchOptionName,
#search_box_button,
.verticalGrayTabs #used,
.search_option_name,
.borderup,
#tour,
#auth,
.ovk-photo-view,
.searchOptions {
.ovk-photo-view {
border-color: #2c2640 !important;
}
@ -155,11 +154,15 @@ hr {
.messagebox-content-header,
.accent-box,
.button_search,
.searchBtn,
.searchOptionName {
.search_box_button {
background-color: #383052;
}
.search_option_name {
background-color: #383052 !important;
color: lightgrey !important;
}
.tab:hover {
background-color: #40375e;
}
@ -176,7 +179,7 @@ hr {
}
.bsdn_contextMenuElement:hover,
.searchList li:hover {
.verticalGrayTabs li:hover {
background-color: #29223a;
}
@ -208,7 +211,7 @@ a,
.paginator a:hover,
.post-share-button:hover,
.post-like-button:hover,
.searchBtn:active {
#search_box_button:active {
background-color: #272138 !important;
}
@ -261,7 +264,9 @@ center[style="background: white;border: #DEDEDE solid 1px;"],
.album-photo img,
#faqhead,
td.e,
tr.e {
tr.e,
.playlistListView:hover,
.playlistListView .playlistCover {
background-color: #231e33 !important;
}
@ -376,7 +381,7 @@ input[type="radio"] {
background-image: url("/themepack/midnight/0.0.2.9/resource/radio.png") !important;
}
.header_navigation .link {
.header_navigation .link, .header_navigation .header_divider_stick {
background: unset;
}
@ -403,15 +408,26 @@ input[type="radio"] {
border-color: #514534;
}
.searchBtn {
#search_box_button {
box-shadow: 0px 2px 0px 0px rgba(111, 111, 111, 0.18) inset;
}
.searchBtn:active {
#search_box_button:active {
box-shadow: 0px -2px 0px 0px rgba(255, 255, 255, 0.18) inset;
}
.searchList #used {
.verticalGrayTabsWrapper {
background: #1e1a2b;
border-top: 1px solid #2c2640;
border-left: 1px solid #2a2841;
}
.page_content_paginator_bottom {
background: #1e1a2b;
border-top: 1px solid #2c2640;
}
.verticalGrayTabs #used {
background: #463f60 !important;
}
@ -447,13 +463,9 @@ input[type="radio"] {
background: #b9b9b9 !important;
}
.musicIcon {
filter: invert(81%) !important;
}
.audioEntry.nowPlaying {
background: #463f60 !important;
border: 1px solid #645a86 !important;
outline: 1px solid #645a86 !important;
}
.preformer {
@ -485,11 +497,11 @@ input[type="radio"] {
color: black !important;
}
.searchList a {
.verticalGrayTabs a {
color: #bbb !important;
}
.searchList a:hover {
.verticalGrayTabs a:hover {
color: #eeeeee !important;
background: #332d46 !important;
}
@ -512,7 +524,7 @@ img[src$='/assets/packages/static/openvk/img/song.jpg'] {
}
.audioEntry .withLyrics {
color: #6f6497 !important;
color: #9481d9 !important;
}
#listensCount {
@ -536,7 +548,8 @@ ul {
/* вот бы css в овк был бы написан на var()'ах( */
#upload_container.uploading {
background: #121017 url('/assets/packages/static/openvk/img/progressbar.gif') !important;
background-color: #312b3f !important;
background-image: url('/assets/packages/static/openvk/img/progressbar.gif') !important;
}
.musicIcon.pressed {
@ -573,3 +586,8 @@ ul {
.add_image_text {
z-index: 999;
}
.content_page_error {
background: #28223a;
border: #2c2640 solid 1px;
}