Compare commits

...

3 commits

Author SHA1 Message Date
mrilyew
fab39bd7fd
Posts: add source param (#934)
* Chopin

- Полностью переписана та часть где про источник поста
- Исправлен метод video.search
- Сокращено число запросов в БД у шаблона поста
- Удалена ссылка на прикреплятор заметок потому что low quality
- Исправлен баг с прикреплённой заметкой в api, но только если ты указал версию.
- Исправлены проблемы с кешированными спрайтшитами

* Chopin 2
2024-11-01 14:46:41 +03:00
ayato
9b220a88db
locales/en.strings: Rephrasing some strings and grammar check (#1098)
* locales: English: fix grammar

* locales: English: fix confusing labels in the repost modal

Clarified modal phrasing when reposting a user's post. The previous wording, 'Share to user's wall,' was ambiguous and could be interpreted as either sharing to your own wall or the original user's wall. Updated the language to make it clear that the post will be shared to your wall.

---------

Co-authored-by: Vladimir Barinov <veselcraft@icloud.com>
2024-11-01 14:00:09 +03:00
ayato
d1bcdaf7d7
Link directly to interests section of the edit page in completeness gauge (#1113) 2024-11-01 13:58:14 +03:00
26 changed files with 466 additions and 142 deletions

View file

@ -74,7 +74,7 @@ final class Video extends VKAPIRequestHandler
$return_items = []; $return_items = [];
$profiles = []; $profiles = [];
$groups = []; $groups = [];
foreach($items as $item) foreach($items as $item) {
$return_item = $item->getApiStructure($this->getUser()); $return_item = $item->getApiStructure($this->getUser());
$return_item = $return_item->video; $return_item = $return_item->video;
$return_items[] = $return_item; $return_items[] = $return_item;
@ -85,6 +85,7 @@ final class Video extends VKAPIRequestHandler
else else
$groups[] = abs($return_item['owner_id']); $groups[] = abs($return_item['owner_id']);
} }
}
if($extended) { if($extended) {
$profiles = array_unique($profiles); $profiles = array_unique($profiles);

View file

@ -102,7 +102,14 @@ final class Wall extends VKAPIRequestHandler
} else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) {
$attachments[] = $attachment->getApiStructure($this->getUser()); $attachments[] = $attachment->getApiStructure($this->getUser());
} else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) {
$attachments[] = $attachment->toVkApiStruct(); if(VKAPI_DECL_VER === '4.100') {
$attachments[] = $attachment->toVkApiStruct();
} else {
$attachments[] = [
'type' => 'note',
'note' => $attachment->toVkApiStruct()
];
}
} else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) {
$attachments[] = [ $attachments[] = [
"type" => "audio", "type" => "audio",
@ -188,6 +195,9 @@ final class Wall extends VKAPIRequestHandler
] ]
]; ];
if($post->hasSource())
$post_temp_obj->copyright = $post->getVkApiCopyright();
if($signerId) if($signerId)
$post_temp_obj->signer_id = $signerId; $post_temp_obj->signer_id = $signerId;
@ -291,7 +301,14 @@ final class Wall extends VKAPIRequestHandler
} else if ($attachment instanceof \openvk\Web\Models\Entities\Video) { } else if ($attachment instanceof \openvk\Web\Models\Entities\Video) {
$attachments[] = $attachment->getApiStructure($this->getUser()); $attachments[] = $attachment->getApiStructure($this->getUser());
} else if ($attachment instanceof \openvk\Web\Models\Entities\Note) { } else if ($attachment instanceof \openvk\Web\Models\Entities\Note) {
$attachments[] = $attachment->toVkApiStruct(); if(VKAPI_DECL_VER === '4.100') {
$attachments[] = $attachment->toVkApiStruct();
} else {
$attachments[] = [
'type' => 'note',
'note' => $attachment->toVkApiStruct()
];
}
} else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) { } else if ($attachment instanceof \openvk\Web\Models\Entities\Audio) {
$attachments[] = [ $attachments[] = [
"type" => "audio", "type" => "audio",
@ -373,6 +390,9 @@ final class Wall extends VKAPIRequestHandler
] ]
]; ];
if($post->hasSource())
$post_temp_obj->copyright = $post->getVkApiCopyright();
if($signerId) if($signerId)
$post_temp_obj->signer_id = $signerId; $post_temp_obj->signer_id = $signerId;
@ -543,6 +563,12 @@ final class Wall extends VKAPIRequestHandler
$post->setFlags($flags); $post->setFlags($flags);
$post->setApi_Source_Name($this->getPlatform()); $post->setApi_Source_Name($this->getPlatform());
if(!is_null($copyright) && !empty($copyright)) {
try {
$post->setSource($copyright);
} catch(\Throwable) {}
}
if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2) if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2)
$post->setSuggested(1); $post->setSuggested(1);
@ -558,11 +584,11 @@ final class Wall extends VKAPIRequestHandler
# Пример: photo1_1 # Пример: photo1_1
if(sizeof($attachmentsArr) > 10) if(sizeof($attachmentsArr) > 10)
$this->fail(50, "Error: too many attachments"); $this->fail(50, "Too many attachments");
preg_match_all("/poll/m", $attachments, $matches, PREG_SET_ORDER, 0); preg_match_all("/poll/m", $attachments, $matches, PREG_SET_ORDER, 0);
if(sizeof($matches) > 1) if(sizeof($matches) > 1)
$this->fail(85, "Error: too many polls"); $this->fail(85, "Too many polls");
foreach($attachmentsArr as $attac) { foreach($attachmentsArr as $attac) {
$attachmentType = NULL; $attachmentType = NULL;
@ -993,7 +1019,7 @@ final class Wall extends VKAPIRequestHandler
} }
} }
function edit(int $owner_id, int $post_id, string $message = "", string $attachments = "") { function edit(int $owner_id, int $post_id, string $message = "", string $attachments = "", string $copyright = NULL) {
$this->requireUser(); $this->requireUser();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
@ -1002,9 +1028,6 @@ final class Wall extends VKAPIRequestHandler
if(!$post || $post->isDeleted()) if(!$post || $post->isDeleted())
$this->fail(102, "Invalid post"); $this->fail(102, "Invalid post");
if(empty($message) && empty($attachments))
$this->fail(100, "Required parameter 'message' missing.");
if(!$post->canBeEditedBy($this->getUser())) if(!$post->canBeEditedBy($this->getUser()))
$this->fail(7, "Access to editing denied"); $this->fail(7, "Access to editing denied");
@ -1012,6 +1035,12 @@ final class Wall extends VKAPIRequestHandler
$post->setContent($message); $post->setContent($message);
$post->setEdited(time()); $post->setEdited(time());
if(!is_null($copyright) && !empty($copyright)) {
try {
$post->setSource($copyright);
} catch(\Throwable) {}
}
$post->save(true); $post->save(true);
# todo добавить такое в веб версию # todo добавить такое в веб версию
@ -1082,6 +1111,63 @@ final class Wall extends VKAPIRequestHandler
return 1; return 1;
} }
function checkCopyrightLink(string $link): int
{
$this->requireUser();
try {
$result = check_copyright_link($link);
} catch(\InvalidArgumentException $e) {
$this->fail(3102, "Specified link is incorrect (can't find source)");
} catch(\LengthException $e) {
$this->fail(3103, "Specified link is incorrect (too long)");
} catch(\LogicException $e) {
$this->fail(3104, "Link is suspicious");
} catch(\Throwable $e) {
$this->fail(3102, "Specified link is incorrect");
}
return 1;
}
function pin(int $owner_id, int $post_id)
{
$this->requireUser();
$this->willExecuteWriteAction();
$post = (new PostsRepo)->getPostById($owner_id, $post_id);
if(!$post || $post->isDeleted())
$this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined");
if(!$post->canBePinnedBy($this->getUser()))
return 0;
if($post->isPinned())
return 1;
$post->pin();
return 1;
}
function unpin(int $owner_id, int $post_id)
{
$this->requireUser();
$this->willExecuteWriteAction();
$post = (new PostsRepo)->getPostById($owner_id, $post_id);
if(!$post || $post->isDeleted())
$this->fail(100, "One of the parameters specified was missing or invalid: post_id is undefined");
if(!$post->canBePinnedBy($this->getUser()))
return 0;
if(!$post->isPinned())
return 1;
$post->unpin();
return 1;
}
private function getApiPhoto($attachment) { private function getApiPhoto($attachment) {
return [ return [
"type" => "photo", "type" => "photo",

View file

@ -78,6 +78,40 @@ class Post extends Postable
{ {
return (bool) $this->getRecord()->pinned; return (bool) $this->getRecord()->pinned;
} }
function hasSource(): bool
{
return $this->getRecord()->source != NULL;
}
function getSource(bool $format = false)
{
$orig_source = $this->getRecord()->source;
if(!str_contains($orig_source, "https://") && !str_contains($orig_source, "http://"))
$orig_source = "https://" . $orig_source;
if(!$format)
return $orig_source;
return $this->formatLinks($orig_source);
}
function setSource(string $source)
{
$result = check_copyright_link($source);
$this->stateChanges("source", $source);
}
function getVkApiCopyright(): object
{
return (object)[
'id' => 0,
'link' => $this->getSource(false),
'name' => $this->getSource(false),
'type' => 'link',
];
}
function isAd(): bool function isAd(): bool
{ {

View file

@ -38,8 +38,19 @@ trait TRichText
$href = str_replace("#", "&num;", $matches[1]); $href = str_replace("#", "&num;", $matches[1]);
$href = rawurlencode(str_replace(";", "&#59;", $href)); $href = rawurlencode(str_replace(";", "&#59;", $href));
$link = str_replace("#", "&num;", $matches[3]); $link = str_replace("#", "&num;", $matches[3]);
# this string breaks ampersands
$link = str_replace(";", "&#59;", $link); $link = str_replace(";", "&#59;", $link);
$rel = $this->isAd() ? "sponsored" : "ugc"; $rel = $this->isAd() ? "sponsored" : "ugc";
$server_domain = str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']);
if(str_contains($link, $server_domain)) {
$replaced_link = str_replace(':' . $_SERVER['SERVER_PORT'], '', $link);
$replaced_link = str_replace($server_domain, '', $replaced_link);
return "<a href='$replaced_link' rel='$rel'>$link</a>" . htmlentities($matches[4]);
}
$link = htmlentities(urldecode($link));
return "<a href='/away.php?to=$href' rel='$rel' target='_blank'>$link</a>" . htmlentities($matches[4]); return "<a href='/away.php?to=$href' rel='$rel' target='_blank'>$link</a>" . htmlentities($matches[4]);
}), }),

View file

@ -367,6 +367,12 @@ final class WallPresenter extends OpenVKPresenter
$post->setFlags($flags); $post->setFlags($flags);
$post->setNsfw($this->postParam("nsfw") === "on"); $post->setNsfw($this->postParam("nsfw") === "on");
if(!empty($this->postParam("source")) && $this->postParam("source") != 'none') {
try {
$post->setSource($this->postParam("source"));
} catch(\Throwable) {}
}
if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2)
$post->setSuggested(1); $post->setSuggested(1);

View file

@ -18,7 +18,7 @@
{else} {else}
<a href="{$owner->getURL()}">{$owner->getCanonicalName()}</a> <a href="{$owner->getURL()}">{$owner->getCanonicalName()}</a>
» »
<a href="/playlists{$ownerId}">{_playlists}</a> <a href="/playlists{$owner->getRealId()}">{_playlists}</a>
» »
<a href="/playlist{$playlist->getPrettyId()}">{_playlist}</a> <a href="/playlist{$playlist->getPrettyId()}">{_playlist}</a>
{/if} {/if}

View file

@ -17,7 +17,7 @@
<a n:if="!$isMy" n:attr="id => $mode === 'list' ? 'used' : 'ki'" href="/audios{$ownerId}">{if $ownerId > 0}{_music_user}{else}{_music_club}{/if}</a> <a n:if="!$isMy" n:attr="id => $mode === 'list' ? 'used' : 'ki'" href="/audios{$ownerId}">{if $ownerId > 0}{_music_user}{else}{_music_club}{/if}</a>
<a href="/player/upload?gid={abs($ownerId)}" n:if="isset($thisUser) && isset($club) && $club->canUploadAudio($thisUser)">{_upload_audio}</a> <a href="/player/upload?gid={abs($ownerId)}" n:if="isset($thisUser) && isset($club) && $club->canUploadAudio($thisUser)">{_upload_audio}</a>
<a n:attr="id => $mode === 'playlists' && $ownerId != $thisUser->getId() ? 'used' : 'ki'" href="/playlists{$ownerId}" n:if="isset($thisUser) && isset($ownerId) && !$isMy">{if $ownerId > 0}{_playlists_user}{else}{_playlists_club}{/if}</a> <a n:attr="id => $mode === 'playlists' && $ownerId != $thisUser->getId() ? 'used' : 'ki'" class='noOverflow' href="/playlists{$ownerId}" n:if="isset($thisUser) && isset($ownerId) && !$isMy">{if $ownerId > 0}{_playlists_user}{else}{_playlists_club}{/if}</a>
<a href="/audios/newPlaylist{if $isMyClub}?gid={abs($ownerId)}{/if}" n:if="isset($thisUser) && $isMyClub">{_new_playlist}</a> <a href="/audios/newPlaylist{if $isMyClub}?gid={abs($ownerId)}{/if}" n:if="isset($thisUser) && $isMyClub">{_new_playlist}</a>
{/if} {/if}
</div> </div>

View file

@ -202,7 +202,7 @@
{if isset($thisUser) && $user->getId() === $thisUser->getId() && sizeof($completeness->unfilled) > 0} {if isset($thisUser) && $user->getId() === $thisUser->getId() && sizeof($completeness->unfilled) > 0}
<br/> <br/>
<a n:if="in_array('interests', $completeness->unfilled)" href="/edit"> <a n:if="in_array('interests', $completeness->unfilled)" href="/edit?act=interests">
<img src="/assets/packages/static/openvk/img/icon1.gif" /> <img src="/assets/packages/static/openvk/img/icon1.gif" />
{_interests} (+20%) {_interests} (+20%)
</a> </a>

View file

@ -18,7 +18,7 @@
</div> </div>
<div n:class="postFeedWrapper, $thisUser->hasMicroblogEnabled() ? postFeedWrapperMicroblog"> <div n:class="postFeedWrapper, $thisUser->hasMicroblogEnabled() ? postFeedWrapperMicroblog">
{include "../components/textArea.xml", route => "/wall" . $thisUser->getId() . "/makePost", graffiti => true, polls => true, notes => true} {include "../components/textArea.xml", route => "/wall" . $thisUser->getId() . "/makePost", graffiti => true, polls => true, notes => true, hasSource => true}
</div> </div>
{foreach $posts as $post} {foreach $posts as $post}

View file

@ -28,7 +28,7 @@
</div> </div>
<div n:if="$canPost && $type == 'all'" class="content_subtitle"> <div n:if="$canPost && $type == 'all'" class="content_subtitle">
{include "../components/textArea.xml", route => "/wall$owner/makePost"} {include "../components/textArea.xml", route => "/wall$owner/makePost", hasSource => true}
</div> </div>
<div class="content"> <div class="content">

View file

@ -1,9 +1,11 @@
{var $author = $comment->getOwner()} {var $author = $comment->getOwner()}
{var $Club = openvk\Web\Models\Entities\Club::class} {var $Club = openvk\Web\Models\Entities\Club::class}
{var $postId = $comment->getTarget() instanceof \openvk\Web\Models\Entities\Post ? $comment->getTarget()->getId() : NULL} {var $likesCount = $comment->getLikesCount()}
{var $target = $comment->getTarget()}
{var $postId = $target instanceof \openvk\Web\Models\Entities\Post ? $target->getId() : NULL}
<a name="cid={$comment->getId()}"></a> <a name="cid={$comment->getId()}"></a>
<table border="0" style="font-size: 11px;" class="post comment" id="_comment{$comment->getId()}" data-comment-id="{$comment->getId()}" data-owner-id="{$author->getId()}" data-from-group="{$comment->getOwner() instanceof $Club}" n:attr="data-post-id => $postId"> <table border="0" style="font-size: 11px;" class="post comment" id="_comment{$comment->getId()}" data-comment-id="{$comment->getId()}" data-owner-id="{$author->getId()}" data-from-group="{$author instanceof $Club}" n:attr="data-post-id => $postId">
<tbody> <tbody>
<tr> <tr>
<td width="30" valign="top"> <td width="30" valign="top">
@ -40,8 +42,8 @@
<span n:if="$comment->getEditTime()" class="edited editedMark">({_edited_short})</span> <span n:if="$comment->getEditTime()" class="edited editedMark">({_edited_short})</span>
</a> </a>
{if !$timeOnly} {if !$timeOnly}
&nbsp;|
{if $comment->canBeDeletedBy($thisUser)} {if $comment->canBeDeletedBy($thisUser)}
|
<a href="/comment{$comment->getId()}/delete">{_delete}</a> <a href="/comment{$comment->getId()}/delete">{_delete}</a>
{/if} {/if}
{if $comment->canBeEditedBy($thisUser)} {if $comment->canBeEditedBy($thisUser)}
@ -60,7 +62,7 @@
<div style="float: right; font-size: .7rem;"> <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)}">
<div class="heart" style="{if $comment->hasLikeFrom($thisUser)}opacity: 1;{else}opacity: 0.4;{/if}"></div> <div class="heart" style="{if $comment->hasLikeFrom($thisUser)}opacity: 1;{else}opacity: 0.4;{/if}"></div>
<span class="likeCnt">{if $comment->getLikesCount() > 0}{$comment->getLikesCount()}{/if}</span> <span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
</a> </a>
</div> </div>
{/if} {/if}
@ -101,4 +103,4 @@
Function.noop Function.noop
]); ]);
} }
</script> </script>

View file

@ -3,6 +3,11 @@
{var $commentsCount = $post->getCommentsCount()} {var $commentsCount = $post->getCommentsCount()}
{var $platform = $post->getPlatform()} {var $platform = $post->getPlatform()}
{var $platformDetails = $post->getPlatformDetails()} {var $platformDetails = $post->getPlatformDetails()}
{var $likesCount = $post->getLikesCount()}
{var $repostsCount = $post->getRepostCount()}
{var $canBePinned = $post->canBePinnedBy($thisUser ?? NULL)}
{var $canBeDeleted = $post->canBeDeletedBy($thisUser)}
{var $wallOwner = $post->getWallOwner()}
{if $post->isDeactivationMessage() && $post->getText()} {if $post->isDeactivationMessage() && $post->getText()}
{var $deac = "post_deact"} {var $deac = "post_deact"}
{else} {else}
@ -30,7 +35,6 @@
{$post->isUpdateAvatarMessage() && !$post->isPostedOnBehalfOfGroup() ? ($author->isFemale() ? tr("upd_f") : ($author->isNeutral() ? tr("upd_n") : tr("upd_m")))} {$post->isUpdateAvatarMessage() && !$post->isPostedOnBehalfOfGroup() ? ($author->isFemale() ? tr("upd_f") : ($author->isNeutral() ? tr("upd_n") : tr("upd_m")))}
{$post->isUpdateAvatarMessage() && $post->isPostedOnBehalfOfGroup() ? tr("upd_g") : ""} {$post->isUpdateAvatarMessage() && $post->isPostedOnBehalfOfGroup() ? tr("upd_g") : ""}
{if ($onWallOf ?? false) &&!$post->isPostedOnBehalfOfGroup() && $post->getOwnerPost() !== $post->getTargetWall()} {if ($onWallOf ?? false) &&!$post->isPostedOnBehalfOfGroup() && $post->getOwnerPost() !== $post->getTargetWall()}
{var $wallOwner = $post->getWallOwner()}
<a href="{$wallOwner->getURL()}" class="mention" data-mention-ref="{$post->getTargetWall()}"> <a href="{$wallOwner->getURL()}" class="mention" data-mention-ref="{$post->getTargetWall()}">
<b> <b>
{if isset($thisUser) && $thisUser->getId() === $post->getTargetWall()} {if isset($thisUser) && $thisUser->getId() === $post->getTargetWall()}
@ -53,9 +57,9 @@
<span n:if="$post->isPinned()" class="nobold">{_pinned}</span> <span n:if="$post->isPinned()" class="nobold">{_pinned}</span>
<a n:if="$post->canBeDeletedBy($thisUser) && !($forceNoDeleteLink ?? false) && $compact == false" class="delete" href="/wall{$post->getPrettyId()}/delete"></a> <a n:if="$canBeDeleted && !($forceNoDeleteLink ?? false) && $compact == false" class="delete" href="/wall{$post->getPrettyId()}/delete"></a>
{if $post->canBePinnedBy($thisUser) && !($forceNoPinLink ?? false) && $compact == false} {if $canBePinned && !($forceNoPinLink ?? false) && $compact == false}
{if $post->isPinned()} {if $post->isPinned()}
<a class="pin" href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}"></a> <a class="pin" href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}"></a>
{else} {else}
@ -67,7 +71,7 @@
<a class="edit" id="editPost" <a class="edit" id="editPost"
data-id="{$post->getId()}" data-id="{$post->getId()}"
data-nsfw="{(int)$post->isExplicit()}" data-nsfw="{(int)$post->isExplicit()}"
{if $post->getTargetWall() < 0 && $post->getWallOwner()->canBeModifiedBy($thisUser)}data-fromgroup="{(int)$post->isPostedOnBehalfOfGroup()}"{/if}></a> {if $post->getTargetWall() < 0 && $wallOwner->canBeModifiedBy($thisUser)}data-fromgroup="{(int)$post->isPostedOnBehalfOfGroup()}"{/if}></a>
{/if} {/if}
</div> </div>
<div class="post-content" id="{$post->getPrettyId()}"> <div class="post-content" id="{$post->getPrettyId()}">
@ -95,6 +99,9 @@
<br/> <br/>
&nbsp;! {_post_is_ad} &nbsp;! {_post_is_ad}
</div> </div>
<div n:if="$post->hasSource()" class="sourceDiv">
<span>{_source}: {$post->getSource(true)|noescape}</span>
</div>
<div n:if="$post->isSigned()" class="post-signature"> <div n:if="$post->isSigned()" class="post-signature">
{var $actualAuthor = $post->getOwner(false)} {var $actualAuthor = $post->getOwner(false)}
<span> <span>
@ -121,14 +128,14 @@
<div class="like_wrap"> <div class="like_wrap">
<a n:if="!($forceNoShareLink ?? false)" id="reposts{$post->getPrettyId()}" class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')"> <a n:if="!($forceNoShareLink ?? false)" id="reposts{$post->getPrettyId()}" class="post-share-button" href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')">
<div class="repost-icon" style="opacity: 0.4;"></div> <div class="repost-icon" style="opacity: 0.4;"></div>
<span class="likeCnt" id="repostsCount{$post->getPrettyId()}">{if $post->getRepostCount() > 0}{$post->getRepostCount()}{/if}</span> <span class="likeCnt" id="repostsCount{$post->getPrettyId()}">{if $repostsCount > 0}{$repostsCount}{/if}</span>
</a> </a>
{if !($forceNoLike ?? false)} {if !($forceNoLike ?? false)}
{var $liked = $post->hasLikeFrom($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="{$post->getLikesCount()}"> <a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
<div class="heart" id="{if $liked}liked{/if}"></div> <div class="heart" id="{if $liked}liked{/if}"></div>
<span class="likeCnt">{if $post->getLikesCount() > 0}{$post->getLikesCount()}{/if}</span> <span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
</a> </a>
{/if} {/if}
</div> </div>
@ -145,7 +152,7 @@
{include "../textArea.xml", route => $commentsURL, postOpts => false, graffiti => (bool) ovkGetQuirk("comments.allow-graffiti"), post => $post, club => $club} {include "../textArea.xml", route => $commentsURL, postOpts => false, graffiti => (bool) ovkGetQuirk("comments.allow-graffiti"), post => $post, club => $club}
</div> </div>
</div> </div>
<div n:if="$suggestion && $post->canBePinnedBy($thisUser ?? NULL)" class="suggestionControls"> <div n:if="$suggestion && $canBePinned" class="suggestionControls">
<input type="button" class="button" id="publish_post" data-id="{$post->getId()}" value="{_publish_suggested}"> <input type="button" class="button" id="publish_post" data-id="{$post->getId()}" value="{_publish_suggested}">
<input type="button" class="button" id="decline_post" data-id="{$post->getId()}" value="{_decline_suggested}"> <input type="button" class="button" id="decline_post" data-id="{$post->getId()}" value="{_decline_suggested}">
</div> </div>

View file

@ -1,6 +1,12 @@
{var $author = $post->getOwner()} {var $author = $post->getOwner()}
{var $platform = $post->getPlatform()} {var $platform = $post->getPlatform()}
{var $platformDetails = $post->getPlatformDetails()} {var $platformDetails = $post->getPlatformDetails()}
{var $wallOwner = $post->getWallOwner()}
{var $likesCount = $post->getLikesCount()}
{var $repostsCount = $post->getRepostCount()}
{var $commentsCount = $post->getCommentsCount()}
{var $canBePinned = $post->canBePinnedBy($thisUser ?? NULL)}
{var $canBeDeleted = $post->canBeDeletedBy($thisUser)}
{if $post->isDeactivationMessage() && $post->getText()} {if $post->isDeactivationMessage() && $post->getText()}
{var $deac = "post_deact"} {var $deac = "post_deact"}
{else} {else}
@ -40,7 +46,6 @@
{/if} {/if}
{/if} {/if}
{if ($onWallOf ?? false) &&!$post->isPostedOnBehalfOfGroup() && $post->getOwnerPost() !== $post->getTargetWall()} {if ($onWallOf ?? false) &&!$post->isPostedOnBehalfOfGroup() && $post->getOwnerPost() !== $post->getTargetWall()}
{var $wallOwner = $post->getWallOwner()}
<a href="{$wallOwner->getURL()}" class="mention" data-mention-ref="{$post->getTargetWall()}"> <a href="{$wallOwner->getURL()}" class="mention" data-mention-ref="{$post->getTargetWall()}">
<b> <b>
{if isset($thisUser) && $thisUser->getId() === $post->getTargetWall()} {if isset($thisUser) && $thisUser->getId() === $post->getTargetWall()}
@ -85,7 +90,7 @@
</div> </div>
</div> </div>
</div> </div>
<div n:if="$suggestion && $post->canBePinnedBy($thisUser ?? NULL)" class="suggestionControls" style="margin-bottom: 7px;"> <div n:if="$suggestion && $canBePinned" class="suggestionControls" style="margin-bottom: 7px;">
<input type="button" class="button" id="publish_post" data-id="{$post->getId()}" value="{_publish_suggested}"> <input type="button" class="button" id="publish_post" data-id="{$post->getId()}" value="{_publish_suggested}">
<input type="button" class="button" id="decline_post" data-id="{$post->getId()}" value="{_decline_suggested}"> <input type="button" class="button" id="decline_post" data-id="{$post->getId()}" value="{_decline_suggested}">
</div> </div>
@ -93,6 +98,9 @@
<br/> <br/>
&nbsp;! {_post_is_ad} &nbsp;! {_post_is_ad}
</div> </div>
<div n:if="$post->hasSource()" class="sourceDiv">
<span>{_source}: {$post->getSource(true)|noescape}</span>
</div>
<div n:if="$post->isSigned()" class="post-signature"> <div n:if="$post->isSigned()" class="post-signature">
{var $actualAuthor = $post->getOwner(false)} {var $actualAuthor = $post->getOwner(false)}
<span> <span>
@ -113,14 +121,14 @@
<a id="editPost" <a id="editPost"
data-id="{$post->getId()}" data-id="{$post->getId()}"
data-nsfw="{(int)$post->isExplicit()}" data-nsfw="{(int)$post->isExplicit()}"
{if $post->getTargetWall() < 0 && $post->getWallOwner()->canBeModifiedBy($thisUser)}data-fromgroup="{(int)$post->isPostedOnBehalfOfGroup()}"{/if}>{_edit}</a> &nbsp;|&nbsp; {if $post->getTargetWall() < 0 && $wallOwner->canBeModifiedBy($thisUser)}data-fromgroup="{(int)$post->isPostedOnBehalfOfGroup()}"{/if}>{_edit}</a> &nbsp;|&nbsp;
{/if} {/if}
{if !($forceNoDeleteLink ?? false) && $post->canBeDeletedBy($thisUser)} {if !($forceNoDeleteLink ?? false) && $canBeDeleted}
<a href="/wall{$post->getPrettyId()}/delete">{_delete}</a> &nbsp;|&nbsp; <a href="/wall{$post->getPrettyId()}/delete">{_delete}</a> &nbsp;|&nbsp;
{/if} {/if}
{if !($forceNoPinLink ?? false) && $post->canBePinnedBy($thisUser)} {if !($forceNoPinLink ?? false) && $canBePinned}
{if $post->isPinned()} {if $post->isPinned()}
<a href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}">{_unpin}</a> <a href="/wall{$post->getPrettyId()}/pin?act=unpin&hash={rawurlencode($csrfToken)}">{_unpin}</a>
{else} {else}
@ -131,8 +139,8 @@
<a n:if="!($forceNoCommentsLink ?? false)" href="/wall{$post->getPrettyId()}#comments"> <a n:if="!($forceNoCommentsLink ?? false)" href="/wall{$post->getPrettyId()}#comments">
{_comments} {_comments}
{if $post->getCommentsCount() > 0} {if $commentsCount > 0}
(<b>{$post->getCommentsCount()}</b>) (<b>{$commentsCount}</b>)
{/if} {/if}
</a> </a>
@ -142,22 +150,22 @@
<a n:if="!($forceNoShareLink ?? false)" id="reposts{$post->getPrettyId()}" class="post-share-button" {ifset $thisUser} href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')"{/ifset}> <a n:if="!($forceNoShareLink ?? false)" id="reposts{$post->getPrettyId()}" class="post-share-button" {ifset $thisUser} href="javascript:repostPost('{$post->getPrettyId()}', '{rawurlencode($csrfToken)}')"{/ifset}>
{_share} {_share}
{if $post->getRepostCount() > 0} {if $repostsCount > 0}
(<b id="repostsCount{$post->getPrettyId()}">{$post->getRepostCount()}</b>) (<b id="repostsCount{$post->getPrettyId()}">{$repostsCount}</b>)
{/if} {/if}
</a> </a>
<div n:if="!($forceNoLike ?? false)" class="like_wrap"> <div n:if="!($forceNoLike ?? false)" class="like_wrap">
{ifset $thisUser} {ifset $thisUser}
{var $liked = $post->hasLikeFrom($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="{$post->getLikesCount()}"> <a href="/wall{$post->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
<div class="heart" id="{if $liked}liked{/if}"></div> <div class="heart" id="{if $liked}liked{/if}"></div>
<span class="likeCnt">{if $post->getLikesCount() > 0}{$post->getLikesCount()}{/if}</span> <span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
</a> </a>
{else} {else}
<a n:if="$post->getLikesCount() > 0" class="post-like-button"> <a n:if="$likesCount > 0" class="post-like-button">
<div class="heart"></div> <div class="heart"></div>
<span class="likeCnt">{$post->getLikesCount()}</span> <span class="likeCnt">{$likesCount}</span>
</a> </a>
{/ifset} {/ifset}
</div> </div>

View file

@ -18,14 +18,15 @@
<div class="post-has-poll"> <div class="post-has-poll">
{_poll} {_poll}
</div> </div>
<div class="post-has-note"> <div class="post-has-note"></div>
</div>
<div class="post-has-videos"></div> <div class="post-has-videos"></div>
<div class="post-has-audios"></div> <div class="post-has-audios"></div>
<div class="post-source"></div>
<div n:if="$postOpts ?? true" class="post-opts"> <div n:if="$postOpts ?? true" class="post-opts">
{var $anonEnabled = OPENVK_ROOT_CONF['openvk']['preferences']['wall']['anonymousPosting']['enable']} {var $anonEnabled = OPENVK_ROOT_CONF['openvk']['preferences']['wall']['anonymousPosting']['enable']}
{if !is_null($thisUser) && !is_null($club ?? NULL) && $owner < 0} {if !is_null($thisUser) && !is_null($club ?? NULL) && $owner < 0}
{if $club->canBeModifiedBy($thisUser)} {if $club->canBeModifiedBy($thisUser)}
<script> <script>
@ -66,6 +67,7 @@
<input type="hidden" name="audios" value="" /> <input type="hidden" name="audios" value="" />
<input type="hidden" name="poll" value="none" /> <input type="hidden" name="poll" value="none" />
<input type="hidden" id="note" name="note" value="none" /> <input type="hidden" id="note" name="note" value="none" />
<input type="hidden" id="source" name="source" value="none" />
<input type="hidden" name="type" value="1" /> <input type="hidden" name="type" value="1" />
<input type="hidden" name="hash" value="{$csrfToken}" /> <input type="hidden" name="hash" value="{$csrfToken}" />
<br/> <br/>
@ -91,10 +93,6 @@
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/mimetypes/audio-ac3.png" /> <img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/mimetypes/audio-ac3.png" />
{_audio} {_audio}
</a> </a>
<a n:if="$notes ?? false" href="javascript:attachNote({$textAreaId})">
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/mimetypes/application-x-srt.png" />
{_note}
</a>
<a n:if="$graffiti ?? false" href="javascript:initGraffiti({$textAreaId});"> <a n:if="$graffiti ?? false" href="javascript:initGraffiti({$textAreaId});">
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/actions/draw-brush.png" /> <img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/actions/draw-brush.png" />
{_graffiti} {_graffiti}
@ -103,6 +101,10 @@
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/actions/office-chart-bar-stacked.png" /> <img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/actions/office-chart-bar-stacked.png" />
{_poll} {_poll}
</a> </a>
<a n:if="$hasSource ?? false" id='__sourceAttacher'>
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/actions/insert-link.png" />
{_source}
</a>
</div> </div>
</div> </div>
</div> </div>

View file

@ -10,7 +10,7 @@
<div class="insertThere" id="postz"></div> <div class="insertThere" id="postz"></div>
<div id="underHeader"> <div id="underHeader">
<div n:if="$canPost" class="content_subtitle"> <div n:if="$canPost" class="content_subtitle">
{include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true, notes => true} {include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true, notes => true, hasSource => true}
</div> </div>
<div class="content"> <div class="content">

View file

@ -70,7 +70,7 @@ class Makima
$result->colSizes = [1]; $result->colSizes = [1];
$result->rowSizes = [1, 1]; $result->rowSizes = [1, 1];
$result->width = ceil($maxWidth); $result->width = ceil($maxWidth);
$result->height = $computedHeight; $result->height = $computedHeight * 2;
$result->tiles = [new ThumbTile(1, 1, $maxWidth, $computedHeight), new ThumbTile(1, 1, $maxWidth, $computedHeight)]; $result->tiles = [new ThumbTile(1, 1, $maxWidth, $computedHeight), new ThumbTile(1, 1, $maxWidth, $computedHeight)];
} else if( } else if(
$orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE] $orients == [Makima::ORIENT_WIDE, Makima::ORIENT_WIDE]

View file

@ -9,7 +9,7 @@
} }
.musicIcon { .musicIcon {
background-image: url('/assets/packages/static/openvk/img/audios_controls.png'); background-image: url('/assets/packages/static/openvk/img/audios_controls.png?v=2');
background-repeat: no-repeat; background-repeat: no-repeat;
cursor: pointer; cursor: pointer;
} }
@ -185,6 +185,7 @@
width: 81%; width: 81%;
height: 13px; height: 13px;
display: inline-block; display: inline-block;
line-height: 14px;
} }
.bigPlayer .paddingLayer .trackInfo .timer span { .bigPlayer .paddingLayer .trackInfo .timer span {
@ -345,6 +346,7 @@
.audioEntry .status .mediaInfo { .audioEntry .status .mediaInfo {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
line-height: 14px;
width: 100%; width: 100%;
} }

View file

@ -44,7 +44,7 @@
._add_image::before { ._add_image::before {
margin-top: 2px; margin-top: 2px;
content: ' '; content: ' ';
background: url('/assets/packages/static/openvk/img/upload.png'); background: url('/assets/packages/static/openvk/img/upload.png?v=2');
width: 10px; width: 10px;
height: 10px; height: 10px;
display: inline-block; display: inline-block;
@ -65,7 +65,7 @@
.avatarDelete::before { .avatarDelete::before {
content: ' '; content: ' ';
background: url('/assets/packages/static/openvk/img/upload.png'); background: url('/assets/packages/static/openvk/img/upload.png?v=2');
background-position: -10px 2px; background-position: -10px 2px;
background-repeat: no-repeat; background-repeat: no-repeat;
width: 12px; width: 12px;

View file

@ -1454,6 +1454,24 @@ body.scrolled .toTop:hover {
color: #3c3c3c; color: #3c3c3c;
} }
.post-source #remove_source_button {
display: inline-block;
background-repeat: no-repeat;
background: url('/assets/packages/static/openvk/img/arrows.png?v=2');
margin-bottom: -2px;
background-position: -18px 0px;
height: 11px;
width: 11px;
opacity: 0.6;
transition-duration: 0.3s;
cursor: pointer;
}
.post-source #remove_source_button:hover {
opacity: 0.8;
}
.post-upload::before, .post-has-poll::before, .post-has-note::before { .post-upload::before, .post-has-poll::before, .post-has-note::before {
content: " "; content: " ";
width: 8px; width: 8px;
@ -3019,6 +3037,26 @@ body.article .floating_sidebar, body.article .page_content {
font-size: 12px; font-size: 12px;
} }
.post .sourceDiv {
margin-top: 3px;
margin-left: 4px;
}
.post .sourceDiv span {
color: grey;
font-size: 10px;
}
.post .sourceDiv a:hover {
text-decoration: underline;
}
#source_flex_kunteynir {
display: flex;
flex-direction: column;
gap: 22px;
}
.sugglist { .sugglist {
padding-bottom: 5px; padding-bottom: 5px;
padding-top: 5px; padding-top: 5px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 316 B

View file

@ -66,16 +66,16 @@ u(`#search_box input[type='search']`).on('input', async (e) => {
switch(section) { switch(section) {
case 'users': case 'users':
results = await fetch(`/method/users.search?auth_mechanism=roaming&q=${query}&count=10&sort=4&fields=photo_50,status,nickname`) results = await fetch(`/method/users.search?auth_mechanism=roaming&q=${encodeURIComponent(query)}&count=10&sort=4&fields=photo_50,status,nickname`)
break break
case 'groups': case 'groups':
results = await fetch(`/method/groups.search?auth_mechanism=roaming&q=${query}&count=10&sort=4&fields=photo_50,description`) results = await fetch(`/method/groups.search?auth_mechanism=roaming&q=${encodeURIComponent(query)}&count=10&sort=4&fields=photo_50,description`)
break break
case 'videos': case 'videos':
results = await fetch(`/method/video.search?auth_mechanism=roaming&q=${query}&count=10&sort=4&extended=1`) results = await fetch(`/method/video.search?auth_mechanism=roaming&q=${encodeURIComponent(query)}&count=10&sort=4&extended=1`)
break break
case 'audios_playlists': case 'audios_playlists':
results = await fetch(`/method/audio.searchAlbums?auth_mechanism=roaming&query=${query}&limit=10`) results = await fetch(`/method/audio.searchAlbums?auth_mechanism=roaming&query=${encodeURIComponent(query)}&limit=10`)
break break
} }

View file

@ -1145,7 +1145,7 @@ $(document).on("click", "#editPost", (e) => {
} }
post.querySelector(".post-avatar").setAttribute("src", result.author.avatar) post.querySelector(".post-avatar").setAttribute("src", result.author.avatar)
post.querySelector(".post-author-name").innerHTML = result.author.name post.querySelector(".post-author-name").innerHTML = result.author.name.escapeHtml()
post.querySelector(".really_text").setAttribute("data-text", result.new_text) post.querySelector(".really_text").setAttribute("data-text", result.new_text)
} else { } else {
MessageBox(tr("error"), result.error, [tr("ok")], [Function.noop]) MessageBox(tr("error"), result.error, [tr("ok")], [Function.noop])
@ -1626,7 +1626,7 @@ $(document).on("click", ".avatarDelete", (e) => {
u("body").removeClass("dimmed"); u("body").removeClass("dimmed");
document.querySelector("html").style.overflowY = "scroll" document.querySelector("html").style.overflowY = "scroll"
u(".ovk-diag-cont").remove(); u(".ovk-diag-cont").remove()
document.querySelector("#bigAvatar").src = response.url document.querySelector("#bigAvatar").src = response.url
document.querySelector("#bigAvatar").parentNode.href = response.new_photo ? ("/photo" + response.new_photo) : "javascript:void(0)" document.querySelector("#bigAvatar").parentNode.href = response.new_photo ? ("/photo" + response.new_photo) : "javascript:void(0)"
@ -1643,3 +1643,77 @@ $(document).on("click", ".avatarDelete", (e) => {
}), }),
]); ]);
}) })
u(document).on('click', '#__sourceAttacher', (e) => {
MessageBox(tr('add_source'), `
<div id='source_flex_kunteynir'>
<span>${tr('set_source_tip')}</span>
<!-- давай, копируй ссылку и переходи по ней -->
<input type='text' maxlength='400' placeholder='https://www.youtube.com/watch?v=lkWuk_nzzVA'>
</div>
`, [tr('cancel')], [
() => {Function.noop}
])
__removeDialog = () => {
u("body").removeClass("dimmed");
document.querySelector("html").style.overflowY = "scroll"
u(".ovk-diag-cont").remove()
}
u('.ovk-diag-action').append(`
<button class='button' id='__setsrcbutton'>${tr('set_source')}</button>
`)
u('.ovk-diag-action #__setsrcbutton').on('click', async (ev) => {
// Consts
const _u_target = u(e.target)
const nearest_textarea = _u_target.closest('#write')
const source_output = nearest_textarea.find(`input[name='source']`)
const source_input = u(`#source_flex_kunteynir input[type='text']`)
const source_value = source_input.nodes[0].value ?? ''
if(source_value.length < 1) {
return
}
ev.target.classList.add('lagged')
// Checking link
const __checkCopyrightLinkRes = await fetch(`/method/wall.checkCopyrightLink?auth_mechanism=roaming&link=${encodeURIComponent(source_value)}`)
const checkCopyrightLink = await __checkCopyrightLinkRes.json()
// todo переписать блять мессенджбоксы чтоб они классами были
if(checkCopyrightLink.error_code) {
__removeDialog()
switch(checkCopyrightLink.error_code) {
default:
case 3102:
fastError(tr('error_adding_source_regex'))
return
case 3103:
fastError(tr('error_adding_source_long'))
return
case 3104:
fastError(tr('error_adding_source_sus'))
return
}
}
// Making indicator
__removeDialog()
source_output.attr('value', source_value)
nearest_textarea.find('.post-source').html(`
<span>${tr('source')}: <a target='_blank' href='${source_value.escapeHtml()}'>${ovk_proc_strtr(source_value.escapeHtml(), 50)}</a></span>
<div id='remove_source_button'></div>
`)
nearest_textarea.find('.post-source #remove_source_button').on('click', () => {
nearest_textarea.find('.post-source').html('')
source_output.attr('value', 'none')
})
})
u('.ovk-diag-body').attr('style', `padding:8px;`)
u('.ovk-diag-cont').attr('style', 'width: 325px;')
u('#source_flex_kunteynir input').nodes[0].focus()
})

View file

@ -286,6 +286,31 @@ function ovk_scheme(bool $with_slashes = false): string
return $scheme; return $scheme;
} }
function check_copyright_link(string $link = ''): bool
{
if(!str_contains($link, "https://") && !str_contains($link, "http://"))
$link = "https://" . $link;
# Existability
if(is_null($link) || empty($link))
throw new \InvalidArgumentException("Empty link");
# Length
if(iconv_strlen($link) < 2 || iconv_strlen($link) > 400)
throw new \LengthException("Link is too long");
# Match URL regex
# stolen from http://urlregex.com/
if (!preg_match("%^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d{1,3}(?:\.\d{1,3}){3}|(?:(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+|xn--[a-z\d-]+)(?:\.(?:[a-z\d\x{00a1}-\x{ffff}]+-?)*[a-z\d\x{00a1}-\x{ffff}]+)*(?:\.(?:xn--[a-z\d-]+|[a-z\x{00a1}-\x{ffff}]{2,6})))(?::\d+)?(?:[^\s]*)?$%iu", $link))
throw new \InvalidArgumentException("Invalid link format");
$banEntries = (new openvk\Web\Models\Repositories\BannedLinks)->check($link);
if(sizeof($banEntries) > 0)
throw new \LogicException("Suspicious link");
return true;
}
return (function() { return (function() {
_ovk_check_environment(); _ovk_check_environment();
require __DIR__ . "/vendor/autoload.php"; require __DIR__ . "/vendor/autoload.php";

View file

@ -0,0 +1,2 @@
ALTER TABLE `posts`
ADD COLUMN `source` TEXT NULL DEFAULT NULL AFTER `api_source_name`;

View file

@ -111,7 +111,7 @@
"relationship_4" = "Married"; "relationship_4" = "Married";
"relationship_5" = "In a civil marriage"; "relationship_5" = "In a civil marriage";
"relationship_6" = "In love"; "relationship_6" = "In love";
"relationship_7" = "Everything is complicated"; "relationship_7" = "It's complicated";
"relationship_8" = "Actively searching"; "relationship_8" = "Actively searching";
/* xd */ /* xd */
@ -122,7 +122,7 @@
"relationship_6_prefix" = "with"; "relationship_6_prefix" = "with";
"relationship_7_prefix" = "with"; "relationship_7_prefix" = "with";
"politViews" = "Polit. Views"; "politViews" = "Political views";
"politViews_0" = "Not Selected"; "politViews_0" = "Not Selected";
"politViews_1" = "Indifferent"; "politViews_1" = "Indifferent";
@ -156,7 +156,7 @@
"updated_at" = "Updated at $1"; "updated_at" = "Updated at $1";
"user_banned" = "Unfortunately, we had to block the <b>$1</b> user page."; "user_banned" = "Unfortunately, we had to block <b>$1's</b> user page.";
"user_banned_comment" = "Moderator's comment:"; "user_banned_comment" = "Moderator's comment:";
"verified_page" = "Verified page"; "verified_page" = "Verified page";
"user_is_blocked" = "User is blocked"; "user_is_blocked" = "User is blocked";
@ -201,11 +201,11 @@
"pin" = "Pin"; "pin" = "Pin";
"unpin" = "Unpin"; "unpin" = "Unpin";
"pinned" = "pinned"; "pinned" = "pinned";
"comments_tip" = "Be first, who leaves a comment at this post!"; "comments_tip" = "Be the first to leave a comment on this post!";
"your_comment" = "Your comment"; "your_comment" = "Your comment";
"auditory" = "Auditory"; "auditory" = "Auditory";
"in_wall" = "to user's wall"; "in_wall" = "to my wall";
"in_group" = "to group"; "in_group" = "to a group";
"shown" = "Shown"; "shown" = "Shown";
"x_out_of" = "$1 of"; "x_out_of" = "$1 of";
"wall_zero" = "no posts"; "wall_zero" = "no posts";
@ -223,6 +223,12 @@
"attachment" = "Attachment"; "attachment" = "Attachment";
"post_as_group" = "Post as group"; "post_as_group" = "Post as group";
"comment_as_group" = "Comment as group"; "comment_as_group" = "Comment as group";
"add_source" = "Add source";
"set_source" = "Apply source";
"source" = "Source";
"set_source_tip" = "If you are using content from other authors, it is important to provide a source to the original.<br>You can do it below.";
"add_signature" = "Add signature"; "add_signature" = "Add signature";
/* ^ can be translated as "author's signature". ^ */ /* ^ can be translated as "author's signature". ^ */
"contains_nsfw" = "Contains NSFW content"; "contains_nsfw" = "Contains NSFW content";
@ -236,7 +242,7 @@
"no_posts_abstract" = "Nobody wrote anything here... So far."; "no_posts_abstract" = "Nobody wrote anything here... So far.";
"attach_no_longer_available" = "This attachment is no longer available."; "attach_no_longer_available" = "This attachment is no longer available.";
"open_post" = "Open post"; "open_post" = "Open post";
"version_incompatibility" = "This attachment could not be displayed. Probably the database is incompatible with the current version of OpenVK."; "version_incompatibility" = "This attachment could not be displayed. Probably because the database is incompatible with the current version of OpenVK.";
"graffiti" = "Graffiti"; "graffiti" = "Graffiti";
@ -317,8 +323,8 @@
"create_group" = "Create group"; "create_group" = "Create group";
"group_managers" = "Managers"; "group_managers" = "Managers";
"group_type" = "Group type"; "group_type" = "Group type";
"group_type_open" = "This is an open group, anyone can enter it."; "group_type_open" = "This is an open group. Anyone can enter it.";
"group_type_closed" = "This is an closed group. To enter, you must submit an request."; "group_type_closed" = "This is a closed group. To enter, you must submit a request.";
"creator" = "Creator"; "creator" = "Creator";
"administrators" = "Administrators"; "administrators" = "Administrators";
"add_to_left_menu" = "Add to left menu"; "add_to_left_menu" = "Add to left menu";
@ -357,12 +363,12 @@
"suggested_by_everyone_many" = "$1 suggested posts"; "suggested_by_everyone_many" = "$1 suggested posts";
"suggested_by_everyone_other" = "$1 suggested posts"; "suggested_by_everyone_other" = "$1 suggested posts";
"group_hide_from_global_feed" = "Don't display posts in the global feed"; "group_hide_from_global_feed" = "Don't display posts in global feed";
"suggested_posts_by_you" = "Suggested posts by you"; "suggested_posts_by_you" = "Your suggested posts";
"suggested_posts_by_everyone" = "Suggested posts"; "suggested_posts_by_everyone" = "Suggested posts";
"suggested" = "Suggested"; "suggested" = "Suggested";
"suggested_posts_everyone" = "Suggested by users posts"; "suggested_posts_everyone" = "Posts suggested by users";
"no_suggested_posts_by_you" = "You haven't suggested posts to this group yet."; "no_suggested_posts_by_you" = "You haven't suggested any post to this group yet.";
"no_suggested_posts_by_people" = "No posts have been suggested to this group yet."; "no_suggested_posts_by_people" = "No posts have been suggested to this group yet.";
"publish_suggested" = "Accept"; "publish_suggested" = "Accept";
@ -377,23 +383,24 @@
"suggested_posts_in_group_many" = "This group has $1 suggested posts"; "suggested_posts_in_group_many" = "This group has $1 suggested posts";
"suggested_posts_in_group_other" = "This group has $1 suggested posts"; "suggested_posts_in_group_other" = "This group has $1 suggested posts";
"suggested_posts_in_group_by_you_zero" = "You haven't suggested any posts to this group"; "suggested_posts_in_group_by_you_zero" = "You haven't suggested any post to this group";
"suggested_posts_in_group_by_you_one" = "You suggested one post to this group"; "suggested_posts_in_group_by_you_one" = "You suggested one post to this group";
"suggested_posts_in_group_by_you_few" = "You suggested $1 posts to this group"; "suggested_posts_in_group_by_you_few" = "You suggested $1 posts to this group";
"suggested_posts_in_group_by_you_many" = "You suggested $1 posts to this group"; "suggested_posts_in_group_by_you_many" = "You suggested $1 posts to this group";
"suggested_posts_in_group_by_you_other" = "You suggested $1 posts to this group"; "suggested_posts_in_group_by_you_other" = "You suggested $1 posts to this group";
"suggestion_succefully_published" = "Post successfully published"; "suggestion_successfully_published" = "Post successfully published";
"suggestion_succefully_declined" = "Post successfully declined"; "suggestion_successfully_declined" = "Post successfully declined";
"suggestion_press_to_go" = "Click to show it"; "suggestion_press_to_go" = "Go to post";
"error_declining_invalid_post" = "Error when declining post: post does not exists"; "error_declining_invalid_post" = "The suggested post you attempted to decline is invalid";
"error_declining_not_suggested_post" = "Error when declining post: post is not suggested"; "error_declining_not_suggested_post" = "The post you attempted to decline is not suggested";
"error_declining_declined_post" = "Error when declining post: post is already declined"; "error_declining_declined_post" = "This suggested post has already been declined";
"error_accepting_invalid_post" = "The suggested post you attempted to accept is invalid";
"error_accepting_not_suggested_post" = "The post you attempted to accept is not suggested";
"error_accepting_declined_post" = "This suggested post has already been declined";
"error_accepting_invalid_post" = "Error when accepting post: post does not exists";
"error_accepting_not_suggested_post" = "Error when accepting post: post is not suggested";
"error_accepting_declined_post" = "Error when accepting post: cant accept declined post";
"statistics" = "Statistics"; "statistics" = "Statistics";
"group_administrators_list" = "Admins list"; "group_administrators_list" = "Admins list";
"group_display_only_creator" = "Display only group creator"; "group_display_only_creator" = "Display only group creator";
@ -483,6 +490,7 @@
"deleting_avatar" = "Deleting photo"; "deleting_avatar" = "Deleting photo";
"deleting_avatar_sure" = "Do you sure you want to delete avatar?"; "deleting_avatar_sure" = "Do you sure you want to delete avatar?";
"deleted_avatar_notification" = "Picture deleted successfully";
"save_changes" = "Save changes"; "save_changes" = "Save changes";
"upd_m" = "updated his profile picture"; "upd_m" = "updated his profile picture";
@ -493,7 +501,7 @@
"add_photos" = "Add photos"; "add_photos" = "Add photos";
"upload_picts" = "Upload photos"; "upload_picts" = "Upload photos";
"end_uploading" = "Finish uploading"; "end_uploading" = "Finish uploading";
"photos_successfully_uploaded" = "Photos successfully uploaded"; "photos_successfully_uploaded" = "Photos uploaded successfully";
"click_to_go_to_album" = "Click here to go to album."; "click_to_go_to_album" = "Click here to go to album.";
"error_uploading_photo" = "Error when uploading photo"; "error_uploading_photo" = "Error when uploading photo";
"too_many_pictures" = "No more than 10 pictures"; "too_many_pictures" = "No more than 10 pictures";
@ -553,10 +561,10 @@
"error_attaching_note" = "Error when attaching note"; "error_attaching_note" = "Error when attaching note";
"select_or_create_new" = "Select existing note or <a href='/notes/create'>create new one</a>"; "select_or_create_new" = "Select an existing note or <a href='/notes/create'>create a new one</a>";
"notes_closed" = "You can't attach note to post, because only you can see them.<br> You can change it in <a href=\"/settings?act=privacy\">settings</a>."; "notes_closed" = "You can't attach a note to the post because only you can see them.<br> You can change this in <a href=\"/settings?act=privacy\">settings</a>.";
"do_not_attach_note" = "Do not attach note"; "do_not_attach_note" = "Do not attach a note";
"something" = "Something"; "something" = "Something";
"supports_xhtml" = "from (X)HTML supported."; "supports_xhtml" = "from (X)HTML supported.";
@ -579,15 +587,15 @@
"my_feed" = "My Feed"; "my_feed" = "My Feed";
"my_feedback" = "My Feedback"; "my_feedback" = "My Feedback";
"my_settings" = "My Settings"; "my_settings" = "My Settings";
"bug_tracker" = "Bug-tracker"; "bug_tracker" = "Bug Tracker";
"menu_settings" = "Settings"; "menu_settings" = "Settings";
"menu_login" = "Login"; "menu_login" = "Login";
"menu_registration" = "Registration"; "menu_registration" = "Register";
"menu_help" = "Help"; "menu_help" = "Help";
"menu_logout" = "Logout"; "menu_logout" = "Log out";
"menu_support" = "Support"; "menu_support" = "Support";
"header_home" = "home"; "header_home" = "home";
@ -834,6 +842,7 @@
/* Audios */ /* Audios */
"my" = "My";
"audios" = "Audios"; "audios" = "Audios";
"audio" = "Audio"; "audio" = "Audio";
"playlist" = "Playlist"; "playlist" = "Playlist";
@ -849,16 +858,16 @@
"limits" = "Limits"; "limits" = "Limits";
"select_audio" = "Select audio from your computer"; "select_audio" = "Select audio from your computer";
"audio_requirements" = "Audio must be between $1 seconds to $2 minutes, weights to $3 MB and contain audio stream."; "audio_requirements" = "Audio must be between $1 seconds and $2 minutes, with a file size up to $3 MB, and contain an audio stream.";
"audio_requirements_2" = "Audio must not infringe copyright and related rights"; "audio_requirements_2" = "Audio must not infringe copyright and related rights.";
"you_can_also_add_audio_using" = "You can also add audio from among the files you have already downloaded using"; "you_can_also_add_audio_using" = "You can also add audio from files you have already downloaded using";
"search_audio_inst" = "audios search"; "search_audio_inst" = "audios search";
"audio_embed_not_found" = "Audio not found"; "audio_embed_not_found" = "Audio not found";
"audio_embed_deleted" = "Audio was deleted"; "audio_embed_deleted" = "Audio has been deleted";
"audio_embed_withdrawn" = "The audio was withdrawn at the request of the copyright holder"; "audio_embed_withdrawn" = "The audio has been withdrawn at the request of the copyright holder";
"audio_embed_forbidden" = "The user's privacy settings do not allow this audio to be embedded"; "audio_embed_forbidden" = "The user's privacy settings do not allow this audio to be embedded";
"audio_embed_processing" = "Audio is still being processed, or has not been processed correctly."; "audio_embed_processing" = "Audio is still being processed or has not been processed correctly.";
"audios_count_zero" = "No audios"; "audios_count_zero" = "No audios";
"audios_count_one" = "One audio"; "audios_count_one" = "One audio";
@ -871,7 +880,7 @@
"my_music" = "My music"; "my_music" = "My music";
"music_user" = "User's music"; "music_user" = "User's music";
"music_club" = "Club's music"; "music_club" = "Group's music";
"audio_new" = "New"; "audio_new" = "New";
"audio_popular" = "Popular"; "audio_popular" = "Popular";
"audio_search" = "Search"; "audio_search" = "Search";
@ -914,19 +923,19 @@
"delete_playlist" = "Delete playlist"; "delete_playlist" = "Delete playlist";
"playlist_cover" = "Playlist cover"; "playlist_cover" = "Playlist cover";
"playlists_user" = "Users playlists"; "playlists_user" = "User's playlists";
"playlists_club" = "Groups playlists"; "playlists_club" = "Group's playlists";
"change_cover" = "Change cover"; "change_cover" = "Change cover";
"playlist_cover" = "Playlist's cover"; "playlist_cover" = "Playlist's cover";
"minutes_count_zero" = "lasts no minutes"; "minutes_count_zero" = "Lasts no minutes";
"minutes_count_one" = "lasts one minute"; "minutes_count_one" = "Lasts one minute";
"minutes_count_few" = "lasts $1 minutes"; "minutes_count_few" = "Lasts $1 minutes";
"minutes_count_many" = "lasts $1 minutes"; "minutes_count_many" = "Lasts $1 minutes";
"minutes_count_other" = "lasts $1 minutes"; "minutes_count_other" = "Lasts $1 minutes";
"listens_count_zero" = "no listens"; "listens_count_zero" = "No listens";
"listens_count_one" = "one listen"; "listens_count_one" = "One listen";
"listens_count_few" = "$1 listens"; "listens_count_few" = "$1 listens";
"listens_count_many" = "$1 listens"; "listens_count_many" = "$1 listens";
"listens_count_other" = "$1 listens"; "listens_count_other" = "$1 listens";
@ -949,7 +958,7 @@
"audio_successfully_uploaded" = "Audio has been successfully uploaded and is currently being processed."; "audio_successfully_uploaded" = "Audio has been successfully uploaded and is currently being processed.";
"broadcast_audio" = "Broadcast audio to status"; "broadcast_audio" = "Broadcast audio to status";
"sure_delete_playlist" = "Do you sure want to delete this playlist?"; "sure_delete_playlist" = "Are you sure you want to delete this playlist?";
"edit_audio" = "Edit audio"; "edit_audio" = "Edit audio";
"audios_group" = "Audios from group"; "audios_group" = "Audios from group";
"playlists_group" = "Playlists from group"; "playlists_group" = "Playlists from group";
@ -1057,7 +1066,7 @@
"coins_count" = "Number of votes"; "coins_count" = "Number of votes";
"message" = "Message"; "message" = "Message";
"failed_to_tranfer_points" = "Failed to transfer votes"; "failed_to_transfer_points" = "Failed to transfer votes";
"points_transfer_successful" = "You have successfully transferred <b>$1</b> to <b><a href=\"$2\">$3</a></b>."; "points_transfer_successful" = "You have successfully transferred <b>$1</b> to <b><a href=\"$2\">$3</a></b>.";
"not_all_information_has_been_entered" = "Not all information has been entered."; "not_all_information_has_been_entered" = "Not all information has been entered.";
@ -1076,8 +1085,8 @@
"apply_voucher" = "Apply voucher"; "apply_voucher" = "Apply voucher";
"failed_to_increase_rating" = "Failed to increase rating"; "failed_to_increase_rating" = "Failed to increase rating";
"rating_increase_successful" = "You have successfully increased rating of <b><a href=\"$1\">$2</a></b> by <b>$3%</b>."; "rating_increase_successful" = "You have successfully increased the rating of <b><a href=\"$1\">$2</a></b> by <b>$3%</b>.";
"negative_rating_value" = "We cannot steal rating from another person, sorry."; "negative_rating_value" = "You can't steal ratings from another person.";
"increased_your_rating_by" = "increased your rating by"; "increased_your_rating_by" = "increased your rating by";
@ -1138,43 +1147,43 @@
"app_withdrawal_empty" = "Sorry, withdrawal of emptiness is not possible."; "app_withdrawal_empty" = "Sorry, withdrawal of emptiness is not possible.";
"app_withdrawal_created" = "A request to withdraw $1 votes has been created. Awaiting crediting."; "app_withdrawal_created" = "A request to withdraw $1 votes has been created. Awaiting crediting.";
"appjs_payment" = "Purchase payment"; "appjs_payment" = "Purchase Payment";
"appjs_payment_intro" = "You are about to pay for an order in the application"; "appjs_payment_intro" = "You are about to pay for an order in the application";
"appjs_order_items" = "Order items"; "appjs_order_items" = "Order items";
"appjs_payment_total" = "Total amount payable"; "appjs_payment_total" = "Total amount payable";
"appjs_payment_confirm" = "Pay"; "appjs_payment_confirm" = "Pay";
"appjs_err_funds" = "Failed to pay: insufficient funds."; "appjs_err_funds" = "Failed to pay: insufficient funds.";
"appjs_wall_post" = "Publish a post"; "appjs_wall_post" = "Publish a Post";
"appjs_wall_post_desc" = "wants to publish a post on your wall"; "appjs_wall_post_desc" = "wants to publish a post on your wall";
"appjs_act_friends" = "your Friends"; "appjs_act_friends" = "Your Friends";
"appjs_act_friends_desc" = "add users as friends and read your friends list"; "appjs_act_friends_desc" = "add users as friends and read your friends list";
"appjs_act_wall" = "your Wall"; "appjs_act_wall" = "Your Wall";
"appjs_act_wall_desc" = "see your news, your wall and create posts on it"; "appjs_act_wall_desc" = "see your news, your wall and create posts on it";
"appjs_act_messages" = "your Messages"; "appjs_act_messages" = "Your Messages";
"appjs_act_messages_desc" = "read and write messages on your behalf"; "appjs_act_messages_desc" = "read and write messages on your behalf";
"appjs_act_groups" = "your Groups"; "appjs_act_groups" = "Your Groups";
"appjs_act_groups_desc" = "see a list of your groups and subscribe you to other"; "appjs_act_groups_desc" = "see a list of your groups and subscribe you to others";
"appjs_act_likes" = "Likes feature"; "appjs_act_likes" = "Likes Feature";
"appjs_act_likes_desc" = "give and take away likes to posts"; "appjs_act_likes_desc" = "give and take away likes to posts";
"appjs_act_request" = "Access request"; "appjs_act_request" = "Access Request";
"appjs_act_requests" = "requests access to"; "appjs_act_requests" = "requests access to";
"appjs_act_can" = "The app will be able to"; "appjs_act_can" = "The app will be able to";
"appjs_act_allow" = "Allow"; "appjs_act_allow" = "Allow";
"appjs_act_disallow" = "Disallow"; "appjs_act_disallow" = "Disallow";
"app_uninstalled" = "Application is disabled"; "app_uninstalled" = "Application Disabled";
"app_uninstalled_desc" = "It will no longer be able to perform actions on your behalf."; "app_uninstalled_desc" = "It will no longer be able to perform actions on your behalf.";
"app_err_not_found" = "Application not found"; "app_err_not_found" = "Application Not Found";
"app_err_not_found_desc" = "Incorrect identifier or it has been disabled."; "app_err_not_found_desc" = "Incorrect identifier or it has been disabled.";
"app_err_forbidden_desc" = "This application is not yours."; "app_err_forbidden_desc" = "This application does not belong to you.";
"app_err_url" = "Incorrect address"; "app_err_url" = "Incorrect Address";
"app_err_url_desc" = "The address of the application did not pass the check, make sure it is correct."; "app_err_url_desc" = "The address of the application did not pass the check; make sure it is correct.";
"app_err_ava" = "Unable to upload an avatar"; "app_err_ava" = "Unable to Upload an Avatar";
"app_err_ava_desc" = "Avatar too big or wrong: general error #$res."; "app_err_ava_desc" = "Avatar is too big or incorrect: general error #$res.";
"app_err_note" = "Failed to attach a news note"; "app_err_note" = "Failed to Attach a News Note";
"app_err_note_desc" = "Make sure the link is correct and the note belongs to you."; "app_err_note_desc" = "Make sure the link is correct and the note belongs to you.";
"learn_more" = "Learn more"; "learn_more" = "Learn more";
@ -1182,7 +1191,7 @@
/* Support */ /* Support */
"support_opened" = "Opened"; "support_opened" = "Opened";
"support_answered" = "With a response"; "support_answered" = "Has a response";
"support_closed" = "Closed"; "support_closed" = "Closed";
"support_ticket" = "Ticket"; "support_ticket" = "Ticket";
"support_tickets" = "Tickets"; "support_tickets" = "Tickets";
@ -1190,28 +1199,28 @@
"support_status_1" = "There's a response"; "support_status_1" = "There's a response";
"support_status_2" = "Closed"; "support_status_2" = "Closed";
"support_greeting_hi" = "Greetings, $1!"; "support_greeting_hi" = "Greetings, $1!";
"support_greeting_regards" = "Best regards,<br/>$1 support team."; "support_greeting_regards" = "Best regards,<br/>$1 Support Team.";
"support_faq" = "Frequently Asked Questions"; "support_faq" = "Frequently Asked Questions";
"support_list" = "List of tickets"; "support_list" = "List of Tickets";
"support_new" = "New ticket"; "support_new" = "New Ticket";
"support_new_title" = "Enter the topic of your ticket"; "support_new_title" = "Enter the topic of your ticket";
"support_new_content" = "Describe the issue or suggestion"; "support_new_content" = "Describe the issue or suggestion";
"reports" = "Reports"; "reports" = "Reports";
"support_rate_good_answer" = "This is good answer"; "support_rate_good_answer" = "This is a good answer";
"support_rate_bad_answer" = "This is bad answer"; "support_rate_bad_answer" = "This is a bad answer";
"support_good_answer_user" = "You left a positive feedback."; "support_good_answer_user" = "You left positive feedback.";
"support_bad_answer_user" = "You left a negative feedback."; "support_bad_answer_user" = "You left negative feedback.";
"support_good_answer_agent" = "User left a positive feedback."; "support_good_answer_agent" = "User left positive feedback.";
"support_bad_answer_agent" = "User left a negative feedback."; "support_bad_answer_agent" = "User left negative feedback.";
"support_rated_good" = "You left a positive feedback about the answer."; "support_rated_good" = "You left positive feedback about the answer.";
"support_rated_bad" = "You left a negative feedback about the answer."; "support_rated_bad" = "You left negative feedback about the answer.";
"wrong_parameters" = "Invalid request parameters."; "wrong_parameters" = "Invalid request parameters.";
"fast_answers" = "Fast answers"; "fast_answers" = "Quick Answers";
"ignore_report" = "Ignore report"; "ignore_report" = "Ignore report";
"report_number" = "Report #"; "report_number" = "Report #";
@ -1306,7 +1315,7 @@
"poll_editor_tips" = "Pressing backspace in empty option will remove it. Use Tab/Enter (in last option) to create new options faster."; "poll_editor_tips" = "Pressing backspace in empty option will remove it. Use Tab/Enter (in last option) to create new options faster.";
"poll_embed" = "Embed code"; "poll_embed" = "Embed code";
"poll_voter_count_zero" = "Be <b>the first one</b> to vote!"; "poll_voter_count_zero" = "Be <b>the first</b> to vote!";
"poll_voter_count_one" = "<b>Only one</b> user voted."; "poll_voter_count_one" = "<b>Only one</b> user voted.";
"poll_voter_count_few" = "<b>$1</b> users voted."; "poll_voter_count_few" = "<b>$1</b> users voted.";
"poll_voter_count_many" = "<b>$1</b> users voted."; "poll_voter_count_many" = "<b>$1</b> users voted.";
@ -1333,7 +1342,7 @@
"messages_other" = "$1 messages"; "messages_other" = "$1 messages";
"topic_messages_count_zero" = "Topic has no messages"; "topic_messages_count_zero" = "Topic has no messages";
"topic_messages_count_one" = "There are one message in the topic"; "topic_messages_count_one" = "There is one message in the topic";
"topic_messages_count_other" = "There are $1 messages in the topic"; "topic_messages_count_other" = "There are $1 messages in the topic";
"replied" = "replied"; "replied" = "replied";
@ -1399,7 +1408,7 @@
"photo_saved" = "Photo saved"; "photo_saved" = "Photo saved";
"photo_saved_comment" = "New profile picture will appear on your page"; "photo_saved_comment" = "New profile picture will appear on your page";
"shared_succ" = "The post will appear on your wall. Click on the notification to go to your wall."; "shared_succ" = "The post will appear on your wall. Click on this notification to go there.";
"invalid_email_address" = "Invalid Email address"; "invalid_email_address" = "Invalid Email address";
"invalid_email_address_comment" = "The Email you entered is not correct."; "invalid_email_address_comment" = "The Email you entered is not correct.";
@ -1553,6 +1562,10 @@
"ffmpeg_not_installed" = "Failed to proccess the file. It looks like ffmpeg is not installed on this server."; "ffmpeg_not_installed" = "Failed to proccess the file. It looks like ffmpeg is not installed on this server.";
"too_many_or_to_lack" = "Too few or too many sources."; "too_many_or_to_lack" = "Too few or too many sources.";
"error_adding_source_regex" = "Error adding source: incorrect link.";
"error_adding_source_long" = "Error adding source: link is too long.";
"error_adding_source_sus" = "Error adding source: suspicious link.";
/* Admin actions */ /* Admin actions */
"login_as" = "Login as $1"; "login_as" = "Login as $1";
@ -1993,6 +2006,7 @@
/* Search */ /* Search */
"s_params" = "Search params";
"s_people" = "Users"; "s_people" = "Users";
"s_groups" = "Clubs"; "s_groups" = "Clubs";
"s_apps" = "Applications"; "s_apps" = "Applications";

View file

@ -207,6 +207,12 @@
"attachment" = "Вложение"; "attachment" = "Вложение";
"post_as_group" = "От имени сообщества"; "post_as_group" = "От имени сообщества";
"comment_as_group" = "От имени сообщества"; "comment_as_group" = "От имени сообщества";
"add_source" = "Добавление источника";
"set_source" = "Указать источник";
"source" = "Источник";
"set_source_tip" = "Если вы используете материалы других авторов, важно указывать ссылку на оригинал.<br>Сделать это вы можете ниже.";
"add_signature" = "Подпись автора"; "add_signature" = "Подпись автора";
"contains_nsfw" = "Содержит NSFW-контент"; "contains_nsfw" = "Содержит NSFW-контент";
"nsfw_warning" = "Данный пост может содержать 18+ контент"; "nsfw_warning" = "Данный пост может содержать 18+ контент";
@ -791,6 +797,7 @@
/* Audios */ /* Audios */
"my" = "Моё";
"audios" = "Аудиозаписи"; "audios" = "Аудиозаписи";
"audio" = "Аудиозапись"; "audio" = "Аудиозапись";
"playlist" = "Плейлист"; "playlist" = "Плейлист";
@ -870,7 +877,7 @@
"remove_from_playlist" = "Удалить из плейлиста"; "remove_from_playlist" = "Удалить из плейлиста";
"delete_playlist" = "Удалить плейлист"; "delete_playlist" = "Удалить плейлист";
"playlist_cover" = "Обложка плейлиста"; "playlist_cover" = "Обложка плейлиста";
"playlists_user" = "Плейлисты польз."; "playlists_user" = "Плейлисты пользователя";
"playlists_club" = "Плейлисты группы"; "playlists_club" = "Плейлисты группы";
"change_cover" = "Сменить обложку"; "change_cover" = "Сменить обложку";
"playlist_cover" = "Обложка плейлиста"; "playlist_cover" = "Обложка плейлиста";
@ -1455,6 +1462,10 @@
"ffmpeg_not_installed" = "Не удалось обработать файл. Похоже, на сервере не установлен ffmpeg."; "ffmpeg_not_installed" = "Не удалось обработать файл. Похоже, на сервере не установлен ffmpeg.";
"too_many_or_to_lack" = "Слишком мало либо слишком много источников."; "too_many_or_to_lack" = "Слишком мало либо слишком много источников.";
"error_adding_source_regex" = "Ошибка добавления источника: некорректная ссылка.";
"error_adding_source_long" = "Ошибка добавления источника: слишком длинная ссылка.";
"error_adding_source_sus" = "Ошибка добавления источника: подозрительная ссылка.";
/* Admin actions */ /* Admin actions */
"login_as" = "Войти как $1"; "login_as" = "Войти как $1";
@ -1883,6 +1894,7 @@
/* Search */ /* Search */
"s_params" = "Параметры поиска";
"s_people" = "Пользователи"; "s_people" = "Пользователи";
"s_groups" = "Группы"; "s_groups" = "Группы";
"s_apps" = "Приложения"; "s_apps" = "Приложения";