mirror of
https://github.com/openvk/openvk
synced 2024-12-22 16:42:32 +03:00
Compare commits
15 commits
2a0b28960a
...
8ea4aba0a5
Author | SHA1 | Date | |
---|---|---|---|
|
8ea4aba0a5 | ||
|
6007a81546 | ||
|
2d0c329a2a | ||
|
4dd9088859 | ||
|
74e998add4 | ||
|
2af8447a0f | ||
|
aff19de2ea | ||
|
cf0b4be3fb | ||
|
14110c409a | ||
|
53e9905ba7 | ||
|
73a067a0c5 | ||
|
da6ce237f4 | ||
|
ba2d929183 | ||
|
0596452ef4 | ||
|
a16e15eaef |
56 changed files with 680 additions and 207 deletions
|
@ -198,7 +198,7 @@ final class Likes extends VKAPIRequestHandler
|
|||
if(!$extended)
|
||||
$res->items[] = $liker->getId();
|
||||
else
|
||||
$res->items[] = $liker->toVkApiStruct();
|
||||
$res->items[] = $liker->toVkApiStruct(NULL, 'photo_50');
|
||||
}
|
||||
|
||||
return $res;
|
||||
|
|
|
@ -39,7 +39,7 @@ class BannedLink extends RowModel
|
|||
|
||||
function getRegexpRule(): string
|
||||
{
|
||||
return addslashes("/" . $this->getDomain() . $this->getRawRegexp() . "/");
|
||||
return "/^" . $this->getDomain() . "\/" . $this->getRawRegexp() . "$/i";
|
||||
}
|
||||
|
||||
function getRawRegexp(): string
|
||||
|
|
|
@ -28,6 +28,11 @@ class Comment extends Post
|
|||
return $entity;
|
||||
}
|
||||
|
||||
function getPageURL(): string
|
||||
{
|
||||
return '#';
|
||||
}
|
||||
|
||||
/**
|
||||
* May return fake owner (group), if flags are [1, (*)]
|
||||
*
|
||||
|
|
|
@ -336,6 +336,11 @@ class Post extends Postable
|
|||
{
|
||||
return $this->getRecord()->suggested;
|
||||
}
|
||||
|
||||
function getPageURL(): string
|
||||
{
|
||||
return "/wall".$this->getPrettyId();
|
||||
}
|
||||
|
||||
function toNotifApiStruct()
|
||||
{
|
||||
|
@ -378,34 +383,70 @@ class Post extends Postable
|
|||
{
|
||||
$domain = ovk_scheme(true).$_SERVER["HTTP_HOST"];
|
||||
$description = $this->getText(false);
|
||||
$title = str_replace("\n", "", ovk_proc_strtr($description, 79));
|
||||
$description_html = $description;
|
||||
$url = $domain."/wall".$this->getPrettyId();
|
||||
|
||||
if($this->isUpdateAvatarMessage())
|
||||
$title = tr('upd_in_general');
|
||||
if($this->isDeactivationMessage())
|
||||
$title = tr('post_deact_in_general');
|
||||
|
||||
$author = $this->getOwner();
|
||||
$author_name = htmlspecialchars($author->getCanonicalName(), ENT_DISALLOWED | ENT_XHTML);
|
||||
$target_wall = $this->getWallOwner();
|
||||
$author_name = escape_html($author->getCanonicalName());
|
||||
if($this->isExplicit())
|
||||
$description_html .= "<br /><b>".tr('contains_nsfw').".</b><br />";
|
||||
$title = 'NSFW: ' . $title;
|
||||
|
||||
foreach($this->getChildren() as $child) {
|
||||
if($child instanceof Photo) {
|
||||
$child_page = $domain.$child->getPageURL();
|
||||
$child_url = $child->getURLBySizeId('large');
|
||||
$description_html .= "<br /><a href='$child_page'><img src='$child_url'></a>";
|
||||
$child_url = $child->getURL();
|
||||
$description_html .= "<br /><a href='$child_page'><img src='$child_url'></a><br />";
|
||||
} elseif($child instanceof Video) {
|
||||
$child_page = $domain.'/video'.$child->getPrettyId();
|
||||
$description_html .= "<br /><a href='$child_page'>Video</a>";
|
||||
|
||||
if($child->getType() != 1) {
|
||||
$description_html .= "".
|
||||
"<br />".
|
||||
"<video width=\"320\" height=\"240\" controls><source src=\"".$child->getURL()."\" type=\"video/mp4\"></video><br />".
|
||||
"<b>".escape_html($child->getName())."</b><br />";
|
||||
} else {
|
||||
$description_html .= "".
|
||||
"<br />".
|
||||
"<a href=\"".$child->getVideoDriver()->getURL()."\"><b>".escape_html($child->getName())."</b></a><br />";
|
||||
}
|
||||
} elseif($child instanceof Audio) {
|
||||
$description_html .= "<br />Audio";
|
||||
if(!$child->isWithdrawn()) {
|
||||
$description_html .= "<br />"
|
||||
."<b>".escape_html($child->getName())."</b>:"
|
||||
."<br />"
|
||||
."<audio controls>"
|
||||
."<source src=\"".$child->getOriginalURL()."\" type=\"audio/mpeg\"></audio>"
|
||||
."<br />";
|
||||
}
|
||||
} elseif($child instanceof Poll) {
|
||||
$description_html .= "<br />".tr('poll').": ".escape_html($child->getTitle());
|
||||
} elseif($child instanceof Note) {
|
||||
$description_html .= "<br />".tr('note').": ".escape_html($child->getName());
|
||||
}
|
||||
}
|
||||
|
||||
$description_html .= "<br />".tr('author').": <img width='15px' src='".$author->getAvatarURL()."'><a href='".$author->getURL()."'>" . $author_name . "</a>";
|
||||
if($this->hasSource()) {
|
||||
$description_html .= "<br />".tr('source').": ".htmlspecialchars($this->getSource(), ENT_DISALLOWED | ENT_XHTML);
|
||||
|
||||
if($target_wall->getRealId() != $author->getRealId())
|
||||
$description_html .= "<br />".tr('on_wall').": <img width='15px' src='".$target_wall->getAvatarURL()."'><a href='".$target_wall->getURL()."'>" . escape_html($target_wall->getCanonicalName()) . "</a>";
|
||||
|
||||
if($this->isSigned()) {
|
||||
$signer = $this->getOwner(false);
|
||||
$description_html .= "<br />".tr('sign_short').": <img width='15px' src='".$signer->getAvatarURL()."'><a href='".$signer->getURL()."'>" . escape_html($signer->getCanonicalName()) . "</a>";
|
||||
}
|
||||
|
||||
if($this->hasSource())
|
||||
$description_html .= "<br />".tr('source').": ".escape_html($this->getSource());
|
||||
|
||||
$item = new \Bhaktaraz\RSSGenerator\Item();
|
||||
$item->title(str_replace("\n", "", ovk_proc_strtr($description, 79)))
|
||||
$item->title($title)
|
||||
->url($url)
|
||||
->guid($url)
|
||||
->creator($author_name)
|
||||
|
|
|
@ -309,6 +309,11 @@ class Video extends Media
|
|||
);
|
||||
}
|
||||
|
||||
function getPageURL(): string
|
||||
{
|
||||
return "/video".$this->getPrettyId();
|
||||
}
|
||||
|
||||
function canBeViewedBy(?User $user = NULL): bool
|
||||
{
|
||||
if($this->isDeleted() || $this->getOwner()->isDeleted()) {
|
||||
|
|
|
@ -3,6 +3,7 @@ namespace openvk\Web\Models\Repositories;
|
|||
use Chandler\Database\DatabaseConnection as DB;
|
||||
use Nette\Database\Table\{ActiveRow, Selection};
|
||||
use openvk\Web\Models\Entities\BannedLink;
|
||||
use function Symfony\Component\Translation\t;
|
||||
|
||||
class BannedLinks
|
||||
{
|
||||
|
@ -43,7 +44,7 @@ class BannedLinks
|
|||
|
||||
function isDomainBanned(string $domain): bool
|
||||
{
|
||||
return sizeof($this->bannedLinks->where(["link" => $domain, "regexp_rule" => ""])) > 0;
|
||||
return sizeof($this->bannedLinks->where(["domain" => $domain, "regexp_rule" => ""])) > 0;
|
||||
}
|
||||
|
||||
function genLinks($rules): \Traversable
|
||||
|
@ -57,12 +58,14 @@ class BannedLinks
|
|||
foreach($links as $link)
|
||||
if (preg_match($link->getRegexpRule(), $uri))
|
||||
yield $link->getId();
|
||||
else if ($this->isDomainBanned($link->getDomain()))
|
||||
yield $link->getId();
|
||||
}
|
||||
|
||||
function check(string $url): ?array
|
||||
{
|
||||
$uri = strstr(str_replace(["https://", "http://"], "", $url), "/", true);
|
||||
$domain = str_replace("www.", "", $uri);
|
||||
$uri = str_replace(["https://", "http://"], "", $url);
|
||||
$domain = explode("/", str_replace("www.", "", $uri))[0];
|
||||
$rules = $this->getByDomain($domain);
|
||||
|
||||
if (is_null($rules))
|
||||
|
|
|
@ -53,7 +53,7 @@ class Posts
|
|||
$offset--;
|
||||
}
|
||||
}
|
||||
} else if(!is_null($offset)) {
|
||||
} else if(!is_null($offset) && $pinPost) {
|
||||
$offset--;
|
||||
}
|
||||
|
||||
|
|
|
@ -481,7 +481,7 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
if ($link) {
|
||||
$link->setDomain($new_domain ?? $this->postParam("link"));
|
||||
$link->setReason($new_reason);
|
||||
$link->setRegexp_rule($this->postParam("regexp"));
|
||||
$link->setRegexp_rule(mb_strlen(trim($this->postParam("regexp"))) > 0 ? $this->postParam("regexp") : "");
|
||||
$link->save();
|
||||
} else {
|
||||
if (!$new_domain)
|
||||
|
@ -490,7 +490,7 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
$link = new BannedLink;
|
||||
$link->setDomain($new_domain);
|
||||
$link->setReason($new_reason);
|
||||
$link->setRegexp_rule($this->postParam("regexp"));
|
||||
$link->setRegexp_rule(mb_strlen(trim($this->postParam("regexp"))) > 0 ? $this->postParam("regexp") : "");
|
||||
$link->setInitiator($this->user->identity->getId());
|
||||
$link->save();
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ final class AwayPresenter extends OpenVKPresenter
|
|||
{
|
||||
function renderAway(): void
|
||||
{
|
||||
$checkBanEntries = (new BannedLinks)->check($this->queryParam("to") . "/");
|
||||
$checkBanEntries = (new BannedLinks)->check($this->queryParam("to"));
|
||||
if (OPENVK_ROOT_CONF["openvk"]["preferences"]["susLinks"]["warnings"])
|
||||
if (sizeof($checkBanEntries) > 0)
|
||||
$this->pass("openvk!Away->view", $checkBanEntries[0]);
|
||||
|
|
|
@ -22,15 +22,10 @@ final class NotesPresenter extends OpenVKPresenter
|
|||
if(!$user->getPrivacyPermission('notes.read', $this->user->identity ?? NULL))
|
||||
$this->flashFail("err", tr("forbidden"), tr("forbidden_comment"));
|
||||
|
||||
$this->template->notes = $this->notes->getUserNotes($user, (int)($this->queryParam("p") ?? 1));
|
||||
$this->template->page = (int)($this->queryParam("p") ?? 1);
|
||||
$this->template->notes = $this->notes->getUserNotes($user, $this->template->page);
|
||||
$this->template->count = $this->notes->getUserNotesCount($user);
|
||||
$this->template->owner = $user;
|
||||
$this->template->paginatorConf = (object) [
|
||||
"count" => $this->template->count,
|
||||
"page" => $this->queryParam("p") ?? 1,
|
||||
"amount" => NULL,
|
||||
"perPage" => OPENVK_DEFAULT_PER_PAGE,
|
||||
];
|
||||
}
|
||||
|
||||
function renderView(int $owner, int $note_id): void
|
||||
|
|
|
@ -283,6 +283,11 @@ abstract class OpenVKPresenter extends SimplePresenter
|
|||
}
|
||||
}
|
||||
|
||||
/*if($this->queryParam('al') == '1') {
|
||||
$this->assertNoCSRF();
|
||||
header('Content-Type: text/plain; charset=UTF-8');
|
||||
}*/
|
||||
|
||||
parent::onStartup();
|
||||
}
|
||||
|
||||
|
|
|
@ -125,5 +125,6 @@ final class SearchPresenter extends OpenVKPresenter
|
|||
];
|
||||
$this->template->extendedPaginatorConf = clone $this->template->paginatorConf;
|
||||
$this->template->extendedPaginatorConf->space = 11;
|
||||
$this->template->paginatorConf->atTop = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -549,66 +549,6 @@ final class WallPresenter extends OpenVKPresenter
|
|||
$this->flashFail("succ", tr("information_-1"), tr("changes_saved_comment"));
|
||||
}
|
||||
|
||||
function renderEdit()
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST")
|
||||
$this->redirect("/id0");
|
||||
|
||||
if($this->postParam("type") == "post")
|
||||
$post = $this->posts->get((int)$this->postParam("postid"));
|
||||
else
|
||||
$post = (new Comments)->get((int)$this->postParam("postid"));
|
||||
|
||||
if(!$post || $post->isDeleted())
|
||||
$this->returnJson(["error" => "Invalid post"]);
|
||||
|
||||
if(!$post->canBeEditedBy($this->user->identity))
|
||||
$this->returnJson(["error" => "Access denied"]);
|
||||
|
||||
$attachmentsCount = sizeof(iterator_to_array($post->getChildren()));
|
||||
|
||||
if(empty($this->postParam("newContent")) && $attachmentsCount < 1)
|
||||
$this->returnJson(["error" => "Empty post"]);
|
||||
|
||||
$post->setEdited(time());
|
||||
|
||||
try {
|
||||
$post->setContent($this->postParam("newContent"));
|
||||
} catch(\LengthException $e) {
|
||||
$this->returnJson(["error" => $e->getMessage()]);
|
||||
}
|
||||
|
||||
if($this->postParam("type") === "post") {
|
||||
$post->setNsfw($this->postParam("nsfw") == "true");
|
||||
$flags = 0;
|
||||
|
||||
if($post->getTargetWall() < 0 && $post->getWallOwner()->canBeModifiedBy($this->user->identity)) {
|
||||
if($this->postParam("fromgroup") == "true") {
|
||||
$flags |= 0b10000000;
|
||||
$post->setFlags($flags);
|
||||
} else
|
||||
$post->setFlags($flags);
|
||||
}
|
||||
}
|
||||
|
||||
$post->save(true);
|
||||
|
||||
$this->returnJson(["error" => "no",
|
||||
"new_content" => $post->getText(),
|
||||
"new_edited" => (string)$post->getEditTime(),
|
||||
"nsfw" => $this->postParam("type") === "post" ? (int)$post->isExplicit() : 0,
|
||||
"from_group" => $this->postParam("type") === "post" && $post->getTargetWall() < 0 ?
|
||||
((int)$post->isPostedOnBehalfOfGroup()) : "false",
|
||||
"new_text" => $post->getText(false),
|
||||
"author" => [
|
||||
"name" => $post->getOwner()->getCanonicalName(),
|
||||
"avatar" => $post->getOwner()->getAvatarUrl()
|
||||
]]);
|
||||
}
|
||||
|
||||
function renderAccept() {
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction(true);
|
||||
|
@ -697,4 +637,44 @@ final class WallPresenter extends OpenVKPresenter
|
|||
"new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId())
|
||||
]);
|
||||
}
|
||||
|
||||
function renderLikers(string $type, int $owner_id, int $item_id)
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
|
||||
$item = NULL;
|
||||
$display_name = $type;
|
||||
switch($type) {
|
||||
default:
|
||||
$this->notFound();
|
||||
break;
|
||||
case 'wall':
|
||||
$item = $this->posts->getPostById($owner_id, $item_id);
|
||||
$display_name = 'post';
|
||||
break;
|
||||
case 'comment':
|
||||
$item = (new \openvk\Web\Models\Repositories\Comments)->get($item_id);
|
||||
break;
|
||||
case 'photo':
|
||||
$item = (new \openvk\Web\Models\Repositories\Photos)->getByOwnerAndVID($owner_id, $item_id);
|
||||
break;
|
||||
case 'video':
|
||||
$item = (new \openvk\Web\Models\Repositories\Videos)->getByOwnerAndVID($owner_id, $item_id);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!$item || $item->isDeleted() || !$item->canBeViewedBy($this->user->identity))
|
||||
$this->notFound();
|
||||
|
||||
$page = (int)($this->queryParam('p') ?? 1);
|
||||
$count = $item->getLikesCount();
|
||||
$likers = iterator_to_array($item->getLikers($page, OPENVK_DEFAULT_PER_PAGE));
|
||||
|
||||
$this->template->item = $item;
|
||||
$this->template->type = $display_name;
|
||||
$this->template->iterator = $likers;
|
||||
$this->template->count = $count;
|
||||
$this->template->page = $page;
|
||||
$this->template->perPage = OPENVK_DEFAULT_PER_PAGE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,14 @@
|
|||
{/if}
|
||||
|
||||
<div class="toTop">
|
||||
⬆ {_to_top}
|
||||
<div id='to_up'>
|
||||
<svg id="to_up_icon" viewBox="0 0 10 6"><polygon points="0 6 5 0 10 6 0 6"/></svg>
|
||||
<span>{_to_top}</span>
|
||||
</div>
|
||||
|
||||
<div id='to_back'>
|
||||
<svg id="to_back_icon" viewBox="0 0 10 6"><polygon points="0 0 5 6 10 0 0 0"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout">
|
||||
|
@ -384,6 +391,7 @@
|
|||
{script "js/al_polls.js"}
|
||||
{script "js/al_suggestions.js"}
|
||||
{script "js/al_navigation.js"}
|
||||
{script "js/al_comments.js"}
|
||||
|
||||
{ifset $thisUser}
|
||||
{script "js/al_notifs.js"}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
{ifset specpage}
|
||||
{include specpage, x => $dat}
|
||||
{else}
|
||||
<div class="container_gray">
|
||||
<div class="container_gray {ifset noscroll}no_scroll_container{else}scroll_container{/ifset}">
|
||||
{var $data = is_array($iterator) ? $iterator : iterator_to_array($iterator)}
|
||||
|
||||
{ifset top}
|
||||
|
@ -27,7 +27,7 @@
|
|||
{/ifset}
|
||||
|
||||
{if sizeof($data) > 0}
|
||||
<div class="content" n:foreach="$data as $dat">
|
||||
<div class="scroll_node content" n:foreach="$data as $dat">
|
||||
<table>
|
||||
<tbody n:attr="id => is_null($table_body_id) ? NULL : $table_body_id">
|
||||
<tr>
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
<div n:if="$audiosCount <= 0" style='height: 50%;'>
|
||||
{include "../components/content_error.xml", description => $ownerId > 0 ? ($ownerId == $thisUser->getId() ? tr("no_audios_thisuser") : tr("no_audios_user")) : tr("no_audios_club")}
|
||||
</div>
|
||||
<div n:if="$audiosCount > 0" class="infContainer">
|
||||
<div class="infObj" n:foreach="$audios as $audio">
|
||||
<div n:if="$audiosCount > 0" class="scroll_container infContainer">
|
||||
<div class="scroll_node infObj" n:foreach="$audios as $audio">
|
||||
{include "player.xml", audio => $audio, club => $club}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -86,10 +86,10 @@
|
|||
{include "../components/content_error.xml", description => $ownerId > 0 ? ($ownerId == $thisUser->getId() ? tr("no_playlists_thisuser") : tr("no_playlists_user")) : tr("no_playlists_club")}
|
||||
</div>
|
||||
|
||||
<div class="infContainer playlistContainer" n:if="$playlistsCount > 0">
|
||||
{foreach $playlists as $playlist}
|
||||
<div class="scroll_container infContainer playlistContainer" n:if="$playlistsCount > 0">
|
||||
<div class='scroll_node' n:foreach='$playlists as $playlist'>
|
||||
{include 'playlistListView.xml', playlist => $playlist}
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -67,11 +67,11 @@
|
|||
<hr style="color: #f7f7f7;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="audiosContainer infContainer" style="margin-top: 14px;">
|
||||
<div class="audiosContainer scroll_container infContainer" style="margin-top: 14px;">
|
||||
{if $count < 1}
|
||||
{_empty_playlist}
|
||||
{else}
|
||||
<div class="infObj" n:foreach="$audios as $audio">
|
||||
<div class="scroll_node" n:foreach="$audios as $audio">
|
||||
{include "player.xml", audio => $audio}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
{/block}
|
||||
|
||||
{block content}
|
||||
<div class="gift_grid">
|
||||
<div n:foreach="$gifts as $gift" n:class="gift_sel, !$gift->canUse($thisUser) ? disabled" data-gift="{$gift->getId()}">
|
||||
<div class="gift_grid scroll_container">
|
||||
<div n:foreach="$gifts as $gift" n:class="scroll_node, gift_sel, !$gift->canUse($thisUser) ? disabled" data-gift="{$gift->getId()}">
|
||||
<img class="gift_pic" src="{$gift->getImage(2)}" alt="{_gift}" loading=lazy />
|
||||
|
||||
<strong class="gift_price">
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
{include "../components/error.xml", title => "", description => $type == "my" ? tr("no_suggested_posts_by_you") : tr("no_suggested_posts_by_people")}
|
||||
{else}
|
||||
<h4 id="cound">{if $type == "my"}{tr("suggested_posts_in_group_by_you", $count)}{else}{tr("suggested_posts_in_group", $count)}{/if}</h4>
|
||||
<div id="postz" class="infContainer">
|
||||
<div id="postz" class="infContainer scroll_container">
|
||||
{var $microblog = $thisUser->hasMicroblogEnabled()}
|
||||
<div class="infObj" n:foreach="$posts as $post">
|
||||
<div class="infObj scroll_node" n:foreach="$posts as $post">
|
||||
{if $microblog}
|
||||
{include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false}
|
||||
{else}
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
</div>
|
||||
|
||||
{if sizeof($corresps) > 0}
|
||||
<div class="crp-list">
|
||||
<div class="crp-list scroll_container">
|
||||
<div n:foreach="$corresps as $coresp"
|
||||
class="crp-entry"
|
||||
class="scroll_node crp-entry"
|
||||
onmousedown="window.location.href = {$coresp->getURL()};" >
|
||||
{var $recipient = $coresp->getCorrespondents()[1]}
|
||||
{var $lastMsg = $coresp->getPreviewMessage()}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{extends "../@listView.xml"}
|
||||
{var $iterator = iterator_to_array($notes)}
|
||||
{var $page = $paginatorConf->page}
|
||||
|
||||
{block title}{_notes}{/block}
|
||||
|
||||
|
@ -60,12 +59,12 @@
|
|||
}
|
||||
</style>
|
||||
|
||||
<div class="container_gray" style="background: white; border-top: none;">
|
||||
<div class="container_gray scroll_container" style="background: white; border-top: none;">
|
||||
|
||||
{var $data = is_array($iterator) ? $iterator : iterator_to_array($iterator)}
|
||||
{if sizeof($data) > 0}
|
||||
|
||||
<div n:foreach="$data as $dat">
|
||||
<div class='scroll_node' n:foreach="$data as $dat">
|
||||
<div class="profile_thumb">
|
||||
<a href="{$owner->getURL()}">
|
||||
<img src="{$owner->getAvatarUrl('miniscule')}" style="width: 50px;">
|
||||
|
@ -106,7 +105,15 @@
|
|||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
|
||||
{include "../components/paginator.xml", conf => (object) [
|
||||
"page" => $page,
|
||||
"count" => $count,
|
||||
"amount" => sizeof($data),
|
||||
"perPage" => 10,
|
||||
"atBottom" => true,
|
||||
]}
|
||||
|
||||
{else}
|
||||
{if isset($thisUser) && $thisUser->getId() == $owner->getId()}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
</div>
|
||||
{var $data = is_array($iterator) ? $iterator : iterator_to_array($iterator)}
|
||||
{if sizeof($data) > 0}
|
||||
<div>
|
||||
<table class="post post-divider" border="0" style="font-size: 11px;" n:foreach="$data as $dat">
|
||||
<div n:class="$mode !== 'new' ? scroll_container">
|
||||
<table class="scroll_node post post-divider" border="0" style="font-size: 11px;" n:foreach="$data as $dat">
|
||||
<tbody>
|
||||
<tr>
|
||||
{var $sxModel = $dat->getModel(1)}
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
{/if}
|
||||
<br/><br/>
|
||||
{if $album->getPhotosCount() > 0}
|
||||
<div class="container_gray album-flex">
|
||||
<div class="container_gray scroll_container album-flex">
|
||||
{foreach $photos as $photo}
|
||||
{php if($photo->isDeleted()) continue; }
|
||||
<div class="album-photo">
|
||||
<div class="album-photo scroll_node">
|
||||
<a
|
||||
n:if="!is_null($thisUser) && $album->canBeModifiedBy($thisUser)"
|
||||
href="/album{$album->getPrettyId()}/remove_photo/{$photo->getId()}" class="album-photo--delete">
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
{var $liked = $photo->hasLikeFrom($thisUser)}
|
||||
{var $likesCount = $photo->getLikesCount()}
|
||||
<div class='like_wrap tidy'>
|
||||
<a href="/photo{$photo->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
|
||||
<a href="/photo{$photo->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}" data-id="{$photo->getPrettyId()}" data-type='photo'>
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
</div>
|
||||
|
||||
<div class='page_wrap_content' id='search_page'>
|
||||
<div n:class='page_wrap_content_main, $section == "audios" && $count > 0 ? audios_padding'>
|
||||
<div n:class='page_wrap_content_main, scroll_container, $section == "audios" && $count > 0 ? audios_padding'>
|
||||
{if $count > 0}
|
||||
{if $section === 'users'}
|
||||
<div class='search_content content def_row_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node search_content content def_row_content' n:foreach="$data as $dat">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
|
@ -125,10 +125,14 @@
|
|||
</div>
|
||||
|
||||
<script n:if='$count > 0 && !empty($query)'>
|
||||
highlightText({$query}, '.page_wrap_content_main', ['text'])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', ['text'])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{elseif $section === 'groups'}
|
||||
<div class='search_content content def_row_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node search_content content def_row_content' n:foreach="$data as $dat">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
|
@ -180,10 +184,14 @@
|
|||
</div>
|
||||
|
||||
<script n:if='$count > 0 && !empty($query)'>
|
||||
highlightText({$query}, '.page_wrap_content_main', ['text', "td[data-highlight='_clubDesc']"])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', ['text', "td[data-highlight='_clubDesc']"])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{elseif $section === 'apps'}
|
||||
<div class='search_content content def_row_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node search_content content def_row_content' n:foreach="$data as $dat">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
|
@ -210,10 +218,14 @@
|
|||
</div>
|
||||
|
||||
<script n:if='$count > 0 && !empty($query)'>
|
||||
highlightText({$query}, '.page_wrap_content_main', ['text', "span[data-highlight='_appDesc']"])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', ['text', "span[data-highlight='_appDesc']"])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{elseif $section === 'posts'}
|
||||
<div class='search_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node search_content' n:foreach="$data as $dat">
|
||||
{if !$dat || $dat->getWallOwner()->isHideFromGlobalFeedEnabled()}
|
||||
{_closed_group_post}.
|
||||
{else}
|
||||
|
@ -222,31 +234,47 @@
|
|||
</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"])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', [".post:not(.comment) > tbody > tr > td > .post-content > .text .really_text"])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{elseif $section === 'videos'}
|
||||
<div class='search_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node search_content' n:foreach="$data as $dat">
|
||||
{include "../components/video.xml", video => $dat}
|
||||
</div>
|
||||
|
||||
<script n:if='$count > 0 && !empty($query)'>
|
||||
highlightText({$query}, '.page_wrap_content_main', [".video_name", ".video_description"])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', [".video_name", ".video_description"])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{elseif $section === 'audios'}
|
||||
<div class='search_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node 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"])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', [".mediaInfo .performer a", ".mediaInfo .title"])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{elseif $section === 'audios_playlists'}
|
||||
<div class='search_content' n:foreach="$data as $dat">
|
||||
<div class='scroll_node 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"])
|
||||
function __scrollHook(page) {
|
||||
highlightText({$query}, '.page_wrap_content_main', [".playlistName", ".playlistDesc"])
|
||||
}
|
||||
|
||||
__scrollHook()
|
||||
</script>
|
||||
{/if}
|
||||
{else}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
{var $iterator = $user->getClubs($page, $admin)}
|
||||
{var $count = $user->getClubCount($admin)}
|
||||
|
||||
{block noscroll}{/block}
|
||||
{block title}
|
||||
{_groups}
|
||||
{/block}
|
||||
|
@ -121,8 +122,8 @@
|
|||
<h4>{_search_group}</h4>
|
||||
<span>{_search_group_desc}</span>
|
||||
<form action="/search">
|
||||
<input name="type" type="hidden" value="groups">
|
||||
<input name="query" class="header_search_input" value="" style="background: none; width: 155px; padding-left: 3px;">
|
||||
<input name="section" type="hidden" value="groups">
|
||||
<input name="q" class="header_search_input" value="" style="background: none; width: 155px; padding-left: 3px;">
|
||||
<button class="button">{_search_by_groups}</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
{/block}
|
||||
|
||||
{block preview}
|
||||
<div class="video-preview" data-id="{$x->getId()}">
|
||||
<div class="video-preview" id="videoOpen" data-id="{$x->getPrettyId()}">
|
||||
<img src="{$x->getThumbnailURL()}"
|
||||
alt="{$x->getName()}"
|
||||
style="max-width: 170px; max-height: 127px; margin: auto;" />
|
||||
|
@ -41,7 +41,7 @@
|
|||
{/block}
|
||||
|
||||
{block name}
|
||||
<span data-id="{$x->getId()}" style="color:unset;">{$x->getName()}</span>
|
||||
<span id="videoOpen" data-id="{$x->getPrettyId()}" 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()}" data-id="{$x->getId()}">{_view_video}</a>
|
||||
<a href="/video{$x->getPrettyId()}" data-id="{$x->getPrettyId()}">{_view_video}</a>
|
||||
{if $x->getCommentsCount() > 0}| <a href="/video{$x->getPrettyId()}#comments">{_comments} ({$x->getCommentsCount()})</a>{/if}
|
||||
</p>
|
||||
{/block}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
{var $liked = $video->hasLikeFrom($thisUser)}
|
||||
{var $likesCount = $video->getLikesCount()}
|
||||
<div class='like_wrap tidy'>
|
||||
<a href="/video{$video->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
|
||||
<a href="/video{$video->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}" data-id="{$video->getPrettyId()}" data-type='video'>
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
{include "../components/textArea.xml", route => "/wall" . $thisUser->getId() . "/makePost", graffiti => true, polls => true, notes => true, hasSource => true}
|
||||
</div>
|
||||
|
||||
{foreach $posts as $post}
|
||||
<a name="postGarter={$post->getId()}"></a>
|
||||
{include "../components/post.xml", post => $post, onWallOf => true, commentSection => true}
|
||||
{/foreach}
|
||||
<div class='scroll_container'>
|
||||
<div class='scroll_node' n:foreach='$posts as $post'>
|
||||
<a name="postGarter={$post->getId()}"></a>
|
||||
{include "../components/post.xml", post => $post, onWallOf => true, commentSection => true}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postFeedBottom">
|
||||
<div class="postFeedPaginator">
|
||||
|
@ -55,8 +57,4 @@
|
|||
window.location.assign(url.replace("__padding", e.target.value));
|
||||
});
|
||||
</script>
|
||||
|
||||
{if isset($thisUser) && $thisUser->hasMicroblogEnabled()}
|
||||
{script "js/al_comments.js"}
|
||||
{/if}
|
||||
{/block}
|
||||
|
|
51
Web/Presenters/templates/Wall/Likers.xml
Normal file
51
Web/Presenters/templates/Wall/Likers.xml
Normal file
|
@ -0,0 +1,51 @@
|
|||
{extends "../@listView.xml"}
|
||||
|
||||
{block title}
|
||||
{_likers_list}
|
||||
{/block}
|
||||
|
||||
{block header}
|
||||
<a href='{$item->getPageURL()}'>{tr($type)}</a> »
|
||||
{_likers_list}
|
||||
{/block}
|
||||
|
||||
{block tabs}
|
||||
<div class="tab" id="activetabs">
|
||||
<a id="act_tab_a" href="#">{_liked_verb}</a>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block link|strip|stripHtml}
|
||||
{$x->getURL()}
|
||||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x->getAvatarUrl('tiny')}" width="75" loading=lazy />
|
||||
{/block}
|
||||
|
||||
{block name}
|
||||
{$x->getCanonicalName()}
|
||||
<img n:if="$x->isVerified()"
|
||||
class="name-checkmark"
|
||||
src="/assets/packages/static/openvk/img/checkmark.png"
|
||||
/>
|
||||
{/block}
|
||||
|
||||
{block description}
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top"><span class="nobold">{_pronouns}: </span></td>
|
||||
<td>{$x->isFemale() ? tr("female") : ($x->isNeutral() ? tr("neutral") : tr("male"))}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top"><span class="nobold">{_relationship}:</span></td>
|
||||
<td>{$x->getLocalizedMaritalStatus()}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top"><span class="nobold">{_registration_date}: </span></td>
|
||||
<td>{$x->getRegistrationTime()}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{/block}
|
|
@ -28,16 +28,16 @@
|
|||
</div>
|
||||
|
||||
<div n:if="$canPost && $type == 'all'" class="content_subtitle">
|
||||
{include "../components/textArea.xml", route => "/wall$owner/makePost", hasSource => true}
|
||||
{include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true, notes => true, hasSource => true}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="content scroll_container">
|
||||
{if sizeof($posts) > 0}
|
||||
{foreach $posts as $post}
|
||||
<div class='scroll_node' n:foreach='$posts as $post'>
|
||||
<a name="postGarter={$post->getId()}"></a>
|
||||
|
||||
{include "../components/post.xml", post => $post, commentSection => true}
|
||||
{/foreach}
|
||||
</div>
|
||||
{include "../components/paginator.xml", conf => $paginatorConf}
|
||||
{else}
|
||||
{_no_posts_abstract}
|
||||
|
@ -45,8 +45,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if isset($thisUser) && $thisUser->hasMicroblogEnabled()}
|
||||
{script "js/al_comments.js"}
|
||||
{/if}
|
||||
{/block}
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
<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)}">
|
||||
<a class="post-like-button" href="/comment{$comment->getId()}/like?hash={rawurlencode($csrfToken)}" data-likes='{$likesCount}' data-id="1_{$comment->getPrettyId()}" data-type='comment'>
|
||||
<div class="heart" style="{if $comment->hasLikeFrom($thisUser)}opacity: 1;{else}opacity: 0.4;{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
</div>
|
||||
|
||||
{if sizeof($comments) > 0}
|
||||
{foreach $comments as $comment}
|
||||
{include "comment.xml", comment => $comment}
|
||||
{/foreach}
|
||||
<div class='scroll_container'>
|
||||
<div class='scroll_node' n:foreach="$comments as $comment">
|
||||
{include "comment.xml", comment => $comment}
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 11px;">
|
||||
{include "paginator.xml", conf => (object) ["page" => $page, "count" => $count, "amount" => sizeof($comments), "perPage" => 10]}
|
||||
</div>
|
||||
{else}
|
||||
{_comments_tip}
|
||||
{/if}
|
||||
|
||||
{script "js/al_comments.js"}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{var $user = $notification->getModel(0)}
|
||||
{var $post = $notification->getModel(1)}
|
||||
|
||||
{_nt_you_were_mentioned_u} <a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a> {$notification->getDateTime()} <a href="/photo{$post->getPageURL()}"><b>{_nt_mention_in_photo}</b></a>: "{$notification->getData()}"
|
||||
{_nt_you_were_mentioned_u} <a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a> {$notification->getDateTime()} <a href="{$post->getPageURL()}"><b>{_nt_mention_in_photo}</b></a>: "{$notification->getData()}"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{var $pageCount = ceil($conf->count / $conf->perPage)}
|
||||
|
||||
<div n:if="!($conf->page === 1 && $conf->count <= $conf->perPage)" n:attr="style => (!$conf->tidy ? 'padding: 8px;')">
|
||||
<div n:class="paginator, ($conf->atBottom ?? false) ? paginator-at-bottom, ($conf->tidy ? 'tidy')">
|
||||
<div n:class="paginator, (($conf->atTop || $atTop) ?? false) ? paginator-at-top, ($conf->atBottom ?? false) ? paginator-at-bottom, ($conf->tidy ? 'tidy')">
|
||||
<a n:if="$conf->page > $space" n:attr="class => ($conf->page === 1 ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => 1]), 'k', '&', PHP_QUERY_RFC3986)}">«</a>
|
||||
{for $j = $conf->page - ($space-1); $j <= $conf->page + ($space-1); $j++}
|
||||
<a n:if="$j > 0 && $j <= $pageCount" n:attr="class => ($conf->page === $j ? 'active')" href="?{http_build_query(array_merge($_GET, ['p' => $j]), 'k', '&', PHP_QUERY_RFC3986)}">{$j}</a>
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
|
||||
{if !($forceNoLike ?? false)}
|
||||
{var $liked = $post->hasLikeFrom($thisUser)}
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}" data-id="{$post->getPrettyId()}" data-type='post'>
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
|
|
|
@ -157,7 +157,7 @@
|
|||
<div n:if="!($forceNoLike ?? false)" class="like_wrap">
|
||||
{ifset $thisUser}
|
||||
{var $liked = $post->hasLikeFrom($thisUser)}
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
|
||||
<a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}" data-id="{$post->getPrettyId()}" data-type='post'>
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<span style="color: grey;">{_video_uploaded} {$video->getPublicationTime()}</span><br/>
|
||||
|
||||
<p>
|
||||
<a href="/video{$video->getPrettyId()}" id='videoOpen' data-id="{$video->getPrettyId()}">{_view_video}</a>
|
||||
<a href="/video{$video->getPrettyId()}" data-id="{$video->getPrettyId()}">{_view_video}</a>
|
||||
{if $video->getCommentsCount() > 0}| <a href="/video{$video->getPrettyId()}#comments">{_comments} ({$video->getCommentsCount()})</a>{/if}
|
||||
</p>
|
||||
{/ifset}
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
{include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true, notes => true, hasSource => true}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="content scroll_container">
|
||||
{if sizeof($posts) > 0}
|
||||
{foreach $posts as $post}
|
||||
<div class='scroll_node' n:foreach='$posts as $post'>
|
||||
<a name="postGarter={$post->getId()}"></a>
|
||||
|
||||
{include "../components/post.xml", post => $post, commentSection => true}
|
||||
{/foreach}
|
||||
</div>
|
||||
{include "../components/paginator.xml", conf => $paginatorConf}
|
||||
{else}
|
||||
{_no_posts_abstract}
|
||||
|
@ -28,7 +28,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if isset($thisUser) && $thisUser->hasMicroblogEnabled()}
|
||||
{script "js/al_comments.js"}
|
||||
{/if}
|
||||
|
|
|
@ -143,6 +143,8 @@ routes:
|
|||
handler: "Wall->accept"
|
||||
- url: "/wall/decline"
|
||||
handler: "Wall->decline"
|
||||
- url: "/{text}/{num}_{num}/likes"
|
||||
handler: "Wall->likers"
|
||||
- url: "/blob_{text}/{?path}.{text}"
|
||||
handler: "Blob->file"
|
||||
placeholders:
|
||||
|
|
|
@ -4,6 +4,7 @@ table.User > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > a:nth-chil
|
|||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
.post > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > a:nth-child(1) > img:nth-child(1)
|
||||
|
@ -11,6 +12,7 @@ table.User > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > a:nth-chil
|
|||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
div.content > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > a:nth-child(1) > img:nth-child(1)
|
||||
|
@ -18,6 +20,7 @@ div.content > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth
|
|||
width: 75px;
|
||||
height: 75px;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
.crp-entry--image > img
|
||||
|
@ -25,6 +28,7 @@ div.content > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth
|
|||
width: 48px;
|
||||
height: 48px;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
.crp-entry--message---av > img,
|
||||
|
@ -33,16 +37,19 @@ div.content > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth
|
|||
width: 42px;
|
||||
height: 42px;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
.cCompactAvatars {
|
||||
width: 30px !important;
|
||||
height: 30px !important;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
||||
.profile_thumb > a > img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
|
|
|
@ -1435,7 +1435,7 @@ textarea {
|
|||
|
||||
.toTop {
|
||||
position: fixed;
|
||||
padding: 20px;
|
||||
padding: 12px;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
background-color: #f3f3f3;
|
||||
|
@ -1445,9 +1445,34 @@ textarea {
|
|||
opacity: 0;
|
||||
transition: .1s all;
|
||||
z-index: 129;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
body.scrolled .toTop:hover {
|
||||
.toTop > div svg {
|
||||
display: inline-block;
|
||||
margin-right: 2px;
|
||||
width: 8px;
|
||||
height: 7px;
|
||||
fill: #3f3f3f;
|
||||
}
|
||||
|
||||
.toTop > div span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toTop.has_down #to_up, .toTop #to_back {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toTop.has_down #to_back {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.toTop.has_down {
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
body.scrolled .toTop:hover, .toTop.has_down:hover {
|
||||
opacity: .5;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -3143,7 +3168,7 @@ body.article .floating_sidebar, body.article .page_content {
|
|||
position: absolute;
|
||||
z-index: 128;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
|
@ -3758,3 +3783,77 @@ hr {
|
|||
height: 206px;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper {
|
||||
box-shadow: 0px 2px 6px -5px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_head {
|
||||
background: linear-gradient(180deg, #595959, #515151);
|
||||
box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.18) inset;
|
||||
border: solid 1px #575757;
|
||||
padding: 4px 10px;
|
||||
width: 180px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_head span, .like_tooltip_wrapper .like_tooltip_head a {
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_body {
|
||||
background: white;
|
||||
padding: 10px;
|
||||
border: 1px solid #878787;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_body .like_tooltip_body_grid {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_body img {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_body a {
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme~="special"] {
|
||||
margin: 0;
|
||||
border: unset;
|
||||
border-radius: 0px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme~="special"] .tippy-arrow {
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme~="special"] .tippy-arrow::before {
|
||||
border-top-color: white;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme~="special"][data-placement^=bottom] .tippy-arrow::before {
|
||||
border-bottom-color: #525252;
|
||||
}
|
||||
|
||||
.tippy-box[data-animation='up_down'] {
|
||||
transition: all 50ms;
|
||||
}
|
||||
|
||||
.tippy-box[data-animation='up_down'][data-state='hidden'] {
|
||||
opacity: 0;
|
||||
inset: auto auto 10px 0px;
|
||||
}
|
||||
|
||||
.tippy-box[data-animation='up_down'][data-state='visible'] {
|
||||
inset: auto auto 0px 0px;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
u(".comment-reply").on("click", function(e) {
|
||||
u(document).on("click", ".comment-reply", function(e) {
|
||||
let comment = u(e.target).closest(".post");
|
||||
let authorId = comment.data("owner-id");
|
||||
let authorNm = u(".post-author > a > b", comment.first()).text().trim();
|
||||
|
@ -8,6 +8,8 @@ u(".comment-reply").on("click", function(e) {
|
|||
let mention = ("[" + (fromGroup ? "club" : "id") + authorId + "|" + authorNm + "], ");
|
||||
|
||||
// Substitute pervious mention if present, prepend otherwise
|
||||
inputbox.nodes[0].value = inputbox.nodes[0].value.replace(/(^\[([A-Za-z0-9]+)\|([\p{L} 0-9@]+)\], |^)/u, mention);
|
||||
inputbox.nodes.forEach(node => {
|
||||
node.value = node.value.replace(/(^\[([A-Za-z0-9]+)\|([\p{L} 0-9@]+)\], |^)/u, mention);
|
||||
})
|
||||
inputbox.trigger("focusin");
|
||||
});
|
||||
|
|
|
@ -84,6 +84,7 @@ u(document).on('click', '#__feed_settings_link', (e) => {
|
|||
const CURRENT_PERPAGE = Number(__temp_url.searchParams.get('posts') ?? 10)
|
||||
const CURRENT_PAGE = Number(__temp_url.searchParams.get('p') ?? 1)
|
||||
const CURRENT_RETURN_BANNED = Number(__temp_url.searchParams.get('return_banned') ?? 0)
|
||||
const CURRENT_AUTO_SCROLL = Number(localStorage.getItem('ux.auto_scroll') ?? 1)
|
||||
const COUNT = [1, 5, 10, 20, 30, 40, 50]
|
||||
u('#_feed_settings_container #__content').html(`
|
||||
<table cellspacing="7" cellpadding="0" border="0" align="center">
|
||||
|
@ -107,11 +108,21 @@ u(document).on('click', '#__feed_settings_link', (e) => {
|
|||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">
|
||||
<input type='checkbox' id="showIgnored" ${CURRENT_RETURN_BANNED == 1 ? 'checked' : ''}>
|
||||
<input type='checkbox' name='showIgnored' id="showIgnored" ${CURRENT_RETURN_BANNED == 1 ? 'checked' : ''}>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
${tr('show_ignored_sources')}
|
||||
<label for='showIgnored'>${tr('show_ignored_sources')}</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">
|
||||
<input type='checkbox' data-act='localstorage_item' name='ux.auto_scroll' id="ux.auto_scroll" ${CURRENT_AUTO_SCROLL == 1 ? 'checked' : ''}>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<label for='ux.auto_scroll'>${tr('auto_scroll')}</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -268,3 +279,7 @@ u(document).on('click', '#__feed_settings_link', (e) => {
|
|||
|
||||
__switchTab('main')
|
||||
})
|
||||
|
||||
u(document).on('change', `input[data-act='localstorage_item']`, (e) => {
|
||||
localStorage.setItem(e.target.name, Number(e.target.checked))
|
||||
})
|
||||
|
|
|
@ -19,7 +19,8 @@ var tooltipTemplate = Handlebars.compile(`
|
|||
</table>
|
||||
`);
|
||||
|
||||
tippy(".mention", {
|
||||
tippy.delegate("body", {
|
||||
target: '.mention',
|
||||
theme: "light vk",
|
||||
content: "⌛",
|
||||
allowHTML: true,
|
||||
|
|
|
@ -631,6 +631,35 @@ class bigPlayer {
|
|||
duration: this.tracks["currentTrack"].length
|
||||
})
|
||||
}
|
||||
|
||||
loadContextPage(page, lesser = false) {
|
||||
const formdata = new FormData()
|
||||
formdata.append("context", this.context["context_type"])
|
||||
formdata.append("context_entity", this.context["context_id"])
|
||||
formdata.append("hash", u("meta[name=csrf]").attr("value"))
|
||||
formdata.append("page", page)
|
||||
|
||||
ky.post("/audios/context", {
|
||||
hooks: {
|
||||
afterResponse: [
|
||||
async (_request, _options, response) => {
|
||||
const newArr = await response.json()
|
||||
|
||||
if(lesser)
|
||||
this.tracks["tracks"] = newArr["items"].concat(this.tracks["tracks"])
|
||||
else
|
||||
this.tracks["tracks"] = this.tracks["tracks"].concat(newArr["items"])
|
||||
|
||||
this.context["playedPages"].push(String(newArr["page"]))
|
||||
|
||||
this.updateButtons()
|
||||
console.info("Loaded context for page " + page)
|
||||
}
|
||||
]
|
||||
},
|
||||
body: formdata
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
|
|
|
@ -201,7 +201,7 @@ $(document).on("click", ".sugglist a", (e) => {
|
|||
})
|
||||
|
||||
// нажатие на пагинатор у постов предложки
|
||||
$(document).on("click", "#postz .paginator a", (e) => {
|
||||
/*$(document).on("click", "#postz .paginator a", (e) => {
|
||||
e.preventDefault()
|
||||
|
||||
ky(e.currentTarget.href, {
|
||||
|
@ -228,4 +228,4 @@ $(document).on("click", "#postz .paginator a", (e) => {
|
|||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
})*/
|
||||
|
|
|
@ -399,6 +399,7 @@ async function OpenVideo(video_arr = [], init_player = true)
|
|||
details.find('.media-page-wrapper-description b').remove()
|
||||
|
||||
u('#ovk-player-info').html(details.html())
|
||||
bsdnHydrate()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -461,7 +462,7 @@ u(document).on('click', '#videoOpen', (e) => {
|
|||
|
||||
u(document).on("keydown", "#write > form", function(event) {
|
||||
if(event.ctrlKey && event.keyCode === 13)
|
||||
this.submit();
|
||||
u(event.target).closest('form').find(`input[type='submit']`).nodes[0].click()
|
||||
});
|
||||
|
||||
u(document).on('keydown', '.edit_menu #write', (e) => {
|
||||
|
@ -542,7 +543,8 @@ var tooltipClientNoInfoTemplate = Handlebars.compile(`
|
|||
</table>
|
||||
`);
|
||||
|
||||
tippy(".client_app", {
|
||||
tippy.delegate("body", {
|
||||
target: '.client_app',
|
||||
theme: "light vk",
|
||||
content: "⌛",
|
||||
allowHTML: true,
|
||||
|
@ -579,6 +581,54 @@ tippy(".client_app", {
|
|||
}
|
||||
});
|
||||
|
||||
tippy.delegate('body', {
|
||||
animation: 'up_down',
|
||||
target: `.post-like-button[data-type]:not([data-likes="0"])`,
|
||||
theme: "special vk",
|
||||
content: "⌛",
|
||||
allowHTML: true,
|
||||
interactive: true,
|
||||
interactiveDebounce: 500,
|
||||
|
||||
onCreate: async function(that) {
|
||||
that._likesList = null;
|
||||
},
|
||||
|
||||
onShow: async function(that) {
|
||||
const id = that.reference.dataset.id
|
||||
const type = that.reference.dataset.type
|
||||
let final_type = type
|
||||
if(type == 'post') {
|
||||
final_type = 'wall'
|
||||
}
|
||||
|
||||
if(!that._likesList) {
|
||||
that._likesList = await window.OVKAPI.call('likes.getList', {'extended': 1, 'count': 6, 'type': type, 'owner_id': id.split('_')[0], 'item_id': id.split('_')[1]})
|
||||
}
|
||||
|
||||
const final_template = u(`
|
||||
<div style='margin: -6px -10px;'>
|
||||
<div class='like_tooltip_wrapper'>
|
||||
<a href="/${final_type}/${id}/likes" class='like_tooltip_head'>
|
||||
<span>${tr('liked_by_x_people', that._likesList.count)}</span>
|
||||
</a>
|
||||
|
||||
<div class='like_tooltip_body'>
|
||||
<div class='like_tooltip_body_grid'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`)
|
||||
|
||||
that._likesList.items.forEach(item => {
|
||||
final_template.find('.like_tooltip_body .like_tooltip_body_grid').append(`
|
||||
<a href='/id${item.id}'><img src='${item.photo_50}' alt='.'></a>
|
||||
`)
|
||||
})
|
||||
that.setContent(final_template.nodes[0].outerHTML)
|
||||
}
|
||||
})
|
||||
|
||||
async function showArticle(note_id) {
|
||||
u("body").addClass("dimmed");
|
||||
let note = await API.Notes.getNote(note_id);
|
||||
|
@ -2003,6 +2053,85 @@ $(document).on("click", ".avatarDelete", (e) => {
|
|||
]);
|
||||
})
|
||||
|
||||
async function __processPaginatorNextPage(page)
|
||||
{
|
||||
const container = u('.scroll_container')
|
||||
const container_node = '.scroll_node'
|
||||
const parser = new DOMParser
|
||||
|
||||
const replace_url = new URL(location.href)
|
||||
replace_url.searchParams.set('p', page)
|
||||
/*replace_url.searchParams.set('al', 1)
|
||||
replace_url.searchParams.set('hash', u("meta[name=csrf]").attr("value"))*/
|
||||
|
||||
const new_content = await fetch(replace_url.href)
|
||||
const new_content_response = await new_content.text()
|
||||
const parsed_content = parser.parseFromString(new_content_response, 'text/html')
|
||||
|
||||
const nodes = parsed_content.querySelectorAll(container_node)
|
||||
nodes.forEach(node => {
|
||||
container.append(node)
|
||||
})
|
||||
|
||||
u(`.paginator:not(.paginator-at-top)`).html(parsed_content.querySelector('.paginator:not(.paginator-at-top)').innerHTML)
|
||||
if(u(`.paginator:not(.paginator-at-top)`).nodes[0].closest('.scroll_container')) {
|
||||
container.nodes[0].append(u(`.paginator:not(.paginator-at-top)`).nodes[0].parentNode)
|
||||
}
|
||||
|
||||
if(window.player) {
|
||||
window.player.loadContextPage(page)
|
||||
}
|
||||
|
||||
if(typeof __scrollHook != 'undefined') {
|
||||
__scrollHook(page)
|
||||
}
|
||||
}
|
||||
|
||||
const showMoreObserver = new IntersectionObserver(entries => {
|
||||
entries.forEach(async x => {
|
||||
if(x.isIntersecting) {
|
||||
if(Number(localStorage.getItem('ux.auto_scroll') ?? 1) == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if(u('.scroll_container').length < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
const target = u(x.target)
|
||||
if(target.length < 1 || target.hasClass('paginator-at-top')) {
|
||||
return
|
||||
}
|
||||
|
||||
const current_url = new URL(location.href)
|
||||
if(current_url.searchParams && !isNaN(parseInt(current_url.searchParams.get('p')))) {
|
||||
return
|
||||
}
|
||||
|
||||
target.addClass('lagged')
|
||||
const active_tab = target.find('.active')
|
||||
const next_page = u(active_tab.nodes[0] ? active_tab.nodes[0].nextElementSibling : null)
|
||||
if(next_page.length < 1) {
|
||||
u('.paginator:not(.paginator-at-top)').removeClass('lagged')
|
||||
return
|
||||
}
|
||||
|
||||
const page_number = Number(next_page.html())
|
||||
await __processPaginatorNextPage(page_number)
|
||||
bsdnHydrate()
|
||||
u('.paginator:not(.paginator-at-top)').removeClass('lagged')
|
||||
}
|
||||
})
|
||||
}, {
|
||||
root: null,
|
||||
rootMargin: '0px',
|
||||
threshold: 0,
|
||||
})
|
||||
|
||||
if(u('.paginator:not(.paginator-at-top)').length > 0) {
|
||||
showMoreObserver.observe(u('.paginator:not(.paginator-at-top)').nodes[0])
|
||||
}
|
||||
|
||||
u(document).on('click', '#__sourceAttacher', (e) => {
|
||||
MessageBox(tr('add_source'), `
|
||||
<div id='source_flex_kunteynir'>
|
||||
|
|
|
@ -63,7 +63,7 @@ document.addEventListener("DOMContentLoaded", function() { //BEGIN
|
|||
});
|
||||
/* @rem-pai why this func wasn't named as "#_deleteDialog"? It looks universal IMO */
|
||||
|
||||
u("#_noteDelete").on("click", function(e) {
|
||||
u(document).on("click", "#_noteDelete", function(e) {
|
||||
var formHtml = "<form id='tmpPhDelF' action='" + u(this).attr("href") + "' >";
|
||||
formHtml += "<input type='hidden' name='hash' value='" + u("meta[name=csrf]").attr("value") + "' />";
|
||||
formHtml += "</form>";
|
||||
|
@ -140,7 +140,7 @@ document.addEventListener("DOMContentLoaded", function() { //BEGIN
|
|||
return false;
|
||||
});
|
||||
|
||||
u("#_submitUserSubscriptionAction").handle("submit", async function(e) {
|
||||
u(document).handle("submit", "#_submitUserSubscriptionAction", async function(e) {
|
||||
u(this).nodes[0].parentElement.classList.add('loading');
|
||||
u(this).nodes[0].parentElement.classList.add('disable');
|
||||
console.log(e.target);
|
||||
|
|
|
@ -1,14 +1,35 @@
|
|||
window.addEventListener("scroll", function(e) {
|
||||
if(window.scrollY < 100) {
|
||||
if(window.temp_y_scroll) {
|
||||
u('.toTop').addClass('has_down')
|
||||
}
|
||||
document.body.classList.toggle("scrolled", false);
|
||||
} else {
|
||||
document.body.classList.toggle("scrolled", true);
|
||||
u('.toTop').removeClass('has_down')
|
||||
}
|
||||
});
|
||||
|
||||
u(".toTop").on("click", function(e) {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth"
|
||||
});
|
||||
});
|
||||
const y_scroll = window.scrollY
|
||||
const scroll_margin = 20
|
||||
|
||||
if(y_scroll > 100) {
|
||||
window.temp_y_scroll = y_scroll
|
||||
window.scrollTo(0, scroll_margin)
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth"
|
||||
})
|
||||
} else {
|
||||
if(window.temp_y_scroll) {
|
||||
window.scrollTo(0, window.temp_y_scroll - scroll_margin)
|
||||
window.scrollTo({
|
||||
top: window.temp_y_scroll,
|
||||
behavior: "smooth"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
u(document).trigger('scroll')
|
||||
})
|
||||
|
|
|
@ -366,6 +366,11 @@ function check_copyright_link(string $link = ''): bool
|
|||
return true;
|
||||
}
|
||||
|
||||
function escape_html(string $unsafe): string
|
||||
{
|
||||
return htmlspecialchars($unsafe, ENT_DISALLOWED | ENT_XHTML);
|
||||
}
|
||||
|
||||
return (function() {
|
||||
_ovk_check_environment();
|
||||
require __DIR__ . "/vendor/autoload.php";
|
||||
|
|
|
@ -220,6 +220,7 @@
|
|||
"all_news" = "All news";
|
||||
"posts_per_page" = "Number of posts per page";
|
||||
"show_ignored_sources" = "Show ignored sources";
|
||||
"auto_scroll" = "Autoscroll";
|
||||
|
||||
"attachment" = "Attachment";
|
||||
"post_as_group" = "Post as group";
|
||||
|
@ -271,6 +272,15 @@
|
|||
"show_more" = "Show more";
|
||||
"has_repost" = "Has repost";
|
||||
|
||||
"likers_list" = "Likers list";
|
||||
"liked_verb" = "Liked by";
|
||||
|
||||
"liked_by_x_people_one" = "Liked by $1 user";
|
||||
"liked_by_x_people_few" = "Liked by $1 users";
|
||||
"liked_by_x_people_many" = "Liked by $1 users";
|
||||
"liked_by_x_people_other" = "Liked by $1 users";
|
||||
"liked_by_x_people_zero" = "Nobody liked";
|
||||
|
||||
/* Friends */
|
||||
|
||||
"friends" = "Friends";
|
||||
|
@ -2226,3 +2236,10 @@
|
|||
|
||||
"roll_back" = "rollback";
|
||||
"roll_backed" = "rollbacked";
|
||||
|
||||
/* RSS */
|
||||
|
||||
"post_deact_in_general" = "Page deletion";
|
||||
"upd_in_general" = "Avatar update";
|
||||
"on_wall" = "On wall";
|
||||
"sign_short" = "Sign";
|
||||
|
|
|
@ -205,6 +205,7 @@
|
|||
"all_news" = "Все новости";
|
||||
"posts_per_page" = "Количество записей на странице";
|
||||
"show_ignored_sources" = "Показывать игнорируемые источники";
|
||||
"auto_scroll" = "Автоматическая прокрутка";
|
||||
"attachment" = "Вложение";
|
||||
"post_as_group" = "От имени сообщества";
|
||||
"comment_as_group" = "От имени сообщества";
|
||||
|
@ -250,6 +251,15 @@
|
|||
"show_more" = "Показать больше";
|
||||
"has_repost" = "Содержит репост";
|
||||
|
||||
"likers_list" = "Список лайкнувших";
|
||||
"liked_verb" = "Понравилось";
|
||||
|
||||
"liked_by_x_people_one" = "Понравилось $1 человеку";
|
||||
"liked_by_x_people_few" = "Понравилось $1 людям";
|
||||
"liked_by_x_people_many" = "Понравилось $1 людям";
|
||||
"liked_by_x_people_other" = "Понравилось $1 людям";
|
||||
"liked_by_x_people_zero" = "Никому не понравилось";
|
||||
|
||||
/* Friends */
|
||||
|
||||
"friends" = "Друзья";
|
||||
|
@ -2117,3 +2127,9 @@
|
|||
"roll_back" = "откатить";
|
||||
"roll_backed" = "откачено";
|
||||
|
||||
/* RSS */
|
||||
|
||||
"post_deact_in_general" = "Удаление страницы";
|
||||
"upd_in_general" = "Обновление фотографии страницы";
|
||||
"on_wall" = "На стене";
|
||||
"sign_short" = "Подпись";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.page_header {
|
||||
background-image: url('/themepack/midnight/0.0.3.1/resource/xheader.png') !important;
|
||||
background-image: url('/themepack/midnight/0.0.3.3/resource/xheader.png') !important;
|
||||
}
|
||||
|
||||
.page_custom_header {
|
||||
background-image: url('/themepack/midnight/0.0.3.1/resource/xheader_custom.png') !important;
|
||||
background-image: url('/themepack/midnight/0.0.3.3/resource/xheader_custom.png') !important;
|
||||
}
|
||||
|
|
|
@ -135,10 +135,18 @@ th,
|
|||
.ovk-photo-view,
|
||||
.page_wrap_content_main .def_row_content,
|
||||
.topGrayBlock,
|
||||
.bigPlayer {
|
||||
.bigPlayer,
|
||||
input[type="number"],
|
||||
.like_tooltip_wrapper .like_tooltip_body,
|
||||
.like_tooltip_wrapper .like_tooltip_head {
|
||||
border-color: #2c2640 !important;
|
||||
}
|
||||
|
||||
.like_tooltip_wrapper .like_tooltip_head {
|
||||
background: linear-gradient(180deg, #383052, #231e33) !important;
|
||||
box-shadow: unset !important;
|
||||
}
|
||||
|
||||
.post-upload,
|
||||
.post-has-poll,
|
||||
.post-has-note {
|
||||
|
@ -187,10 +195,8 @@ hr {
|
|||
.ovk-diag-action,
|
||||
.minilink .counter,
|
||||
.topGrayBlock,
|
||||
.showMore,
|
||||
.showMoreAudiosPlaylist,
|
||||
#showMorePhotos,
|
||||
#showMoreVideos {
|
||||
#show_more,
|
||||
.information {
|
||||
background-color: #2c2640 !important;
|
||||
}
|
||||
|
||||
|
@ -232,7 +238,8 @@ a,
|
|||
.paginator a:hover,
|
||||
.post-share-button:hover,
|
||||
.post-like-button:hover,
|
||||
#search_box_button:active {
|
||||
#search_box_button:active,
|
||||
.mb_tab:hover {
|
||||
background-color: #272138 !important;
|
||||
}
|
||||
|
||||
|
@ -288,7 +295,8 @@ td.e,
|
|||
tr.e,
|
||||
.playlistListView:hover,
|
||||
.playlistListView .playlistCover,
|
||||
.photosInsert > div {
|
||||
.photosInsert > div,
|
||||
.attachment_selector #attachment_insert #attachment_insert_count {
|
||||
background-color: #231e33 !important;
|
||||
}
|
||||
|
||||
|
@ -307,7 +315,8 @@ tr.v,
|
|||
.expand_button,
|
||||
#userContent blockquote,
|
||||
.tippy-box[data-theme~="vk"],
|
||||
.searchOptions {
|
||||
.searchOptions,
|
||||
.like_tooltip_wrapper .like_tooltip_body {
|
||||
background-color: #1e1a2b !important;
|
||||
}
|
||||
|
||||
|
@ -317,11 +326,11 @@ tr.v,
|
|||
}
|
||||
|
||||
.content_title_expanded {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/flex_arrow_open.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/flex_arrow_open.png") !important;
|
||||
}
|
||||
|
||||
.content_title_unexpanded {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/flex_arrow_shut.gif") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/flex_arrow_shut.gif") !important;
|
||||
}
|
||||
|
||||
.ovk-video>.preview,
|
||||
|
@ -348,17 +357,17 @@ tr.h {
|
|||
|
||||
.page_yellowheader {
|
||||
color: #c6d2e8;
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/header_purple.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/header_purple.png") !important;
|
||||
background-color: #231f34;
|
||||
border-color: #231f34;
|
||||
}
|
||||
|
||||
.page_header {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/header.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/header.png") !important;
|
||||
}
|
||||
|
||||
.page_custom_header {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/header_custom.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/header_custom.png") !important;
|
||||
}
|
||||
|
||||
.page_yellowheader span,
|
||||
|
@ -390,17 +399,18 @@ input[type~="phone"],
|
|||
input[type="search"],
|
||||
input[type~="search"],
|
||||
input[type~="date"],
|
||||
input[type="number"],
|
||||
select,
|
||||
.crp-entry--message.unread {
|
||||
background-color: #181826 !important;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/checkbox.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/checkbox.png") !important;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/radio.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/radio.png") !important;
|
||||
}
|
||||
|
||||
.header_navigation .link, .header_navigation .header_divider_stick {
|
||||
|
@ -408,20 +418,20 @@ input[type="radio"] {
|
|||
}
|
||||
|
||||
.heart {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/like.gif") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/like.gif") !important;
|
||||
}
|
||||
|
||||
.pinned-mark,
|
||||
.post-author .pin {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/pin.png") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/pin.png") !important;
|
||||
}
|
||||
|
||||
.repost-icon {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/published.gif") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/published.gif") !important;
|
||||
}
|
||||
|
||||
.post-author .delete {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/input_clear.gif") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/input_clear.gif") !important;
|
||||
}
|
||||
|
||||
.user-alert {
|
||||
|
@ -454,7 +464,7 @@ input[type="radio"] {
|
|||
}
|
||||
|
||||
#backdropEditor {
|
||||
background-image: url("/themepack/midnight/0.0.3.1/resource/backdrop-editor.gif") !important;
|
||||
background-image: url("/themepack/midnight/0.0.3.3/resource/backdrop-editor.gif") !important;
|
||||
border-color: #473e66 !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
id: midnight
|
||||
version: "0.0.3.1"
|
||||
version: "0.0.3.3"
|
||||
openvk_version: 0
|
||||
enabled: 1
|
||||
metadata:
|
||||
|
|
Loading…
Reference in a new issue