mirror of
https://github.com/openvk/openvk
synced 2024-12-24 01:21:07 +03:00
Merge branch 'master' into bug-tracker
This commit is contained in:
commit
52c19e1f48
42 changed files with 991 additions and 391 deletions
|
@ -152,6 +152,7 @@ final class Messages extends VKAPIRequestHandler
|
|||
$this->requireUser();
|
||||
|
||||
$convos = (new MSGRepo)->getCorrespondencies($this->getUser(), -1, $count, $offset);
|
||||
$convosCount = (new MSGRepo)->getCorrespondenciesCount($this->getUser());
|
||||
$list = [];
|
||||
|
||||
$users = [];
|
||||
|
@ -195,9 +196,8 @@ final class Messages extends VKAPIRequestHandler
|
|||
$lastMessagePreview->body = $lastMessage->getText(false);
|
||||
$lastMessagePreview->text = $lastMessage->getText(false);
|
||||
$lastMessagePreview->emoji = true;
|
||||
|
||||
|
||||
if($extended == 1) {
|
||||
$users[] = $lastMessage->getSender()->getId();
|
||||
$users[] = $author;
|
||||
}
|
||||
}
|
||||
|
@ -210,16 +210,17 @@ final class Messages extends VKAPIRequestHandler
|
|||
|
||||
if($extended == 0){
|
||||
return (object) [
|
||||
"count" => sizeof($list),
|
||||
"count" => $convosCount,
|
||||
"items" => $list,
|
||||
];
|
||||
} else {
|
||||
$users[] = $this->getUser()->getId();
|
||||
$users = array_unique($users);
|
||||
|
||||
return (object) [
|
||||
"count" => sizeof($list),
|
||||
"count" => $convosCount,
|
||||
"items" => $list,
|
||||
"profiles" => (!empty($users) ? (new APIUsers)->get(implode(',', $users), $fields, $offset, $count) : [])
|
||||
"profiles" => (!empty($users) ? (new APIUsers)->get(implode(',', $users), $fields, 0, $count+1) : [])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +284,7 @@ final class Messages extends VKAPIRequestHandler
|
|||
return (object) $output;
|
||||
}
|
||||
|
||||
function getHistory(int $offset = 0, int $count = 20, int $user_id = -1, int $peer_id = -1, int $start_message_id = 0, int $rev = 0, int $extended = 0): object
|
||||
function getHistory(int $offset = 0, int $count = 20, int $user_id = -1, int $peer_id = -1, int $start_message_id = 0, int $rev = 0, int $extended = 0, string $fields = ""): object
|
||||
{
|
||||
$this->requireUser();
|
||||
|
||||
|
@ -315,10 +316,18 @@ final class Messages extends VKAPIRequestHandler
|
|||
$results[] = $rMsg;
|
||||
}
|
||||
|
||||
return (object) [
|
||||
$output = [
|
||||
"count" => sizeof($results),
|
||||
"items" => $results,
|
||||
];
|
||||
|
||||
if ($extended == 1) {
|
||||
$users[] = $this->getUser()->getId();
|
||||
$users[] = $user_id;
|
||||
$output["profiles"] = (!empty($users) ? (new APIUsers($this->getUser()))->get(implode(',', $users), $fields) : []);
|
||||
}
|
||||
|
||||
return (object) $output;
|
||||
}
|
||||
|
||||
function getLongPollHistory(int $ts = -1, int $preview_length = 0, int $events_limit = 1000, int $msgs_limit = 1000): object
|
||||
|
|
|
@ -26,7 +26,7 @@ final class Newsfeed extends VKAPIRequestHandler
|
|||
->select("id")
|
||||
->where("wall IN (?)", $ids)
|
||||
->where("deleted", 0)
|
||||
->where("created < (?)", empty($start_from) ? time()+1 : $start_from)
|
||||
->where("id < (?)", empty($start_from) ? time()+1 : $start_from)
|
||||
->order("created DESC");
|
||||
|
||||
$rposts = [];
|
||||
|
@ -34,7 +34,7 @@ final class Newsfeed extends VKAPIRequestHandler
|
|||
$rposts[] = (new PostsRepo)->get($post->id)->getPrettyId();
|
||||
|
||||
$response = (new Wall)->getById(implode(',', $rposts), $extended, $fields, $this->getUser());
|
||||
$response->next_from = end($response->items)->date;
|
||||
$response->next_from = end(end($posts->page((int) ($offset + 1), $count))); // ну и костыли пиздец конечно)
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ final class Users extends VKAPIRequestHandler
|
|||
$user_ids = (string) $authuser->getId();
|
||||
|
||||
$usrs = explode(',', $user_ids);
|
||||
$response;
|
||||
$response = array();
|
||||
|
||||
$ic = sizeof($usrs);
|
||||
|
||||
|
@ -24,117 +24,122 @@ final class Users extends VKAPIRequestHandler
|
|||
$usrs = array_slice($usrs, $offset * $count);
|
||||
|
||||
for($i=0; $i < $ic; $i++) {
|
||||
$usr = $users->get((int) $usrs[$i]);
|
||||
if(is_null($usr) || $usr->isDeleted()) {
|
||||
$response[$i] = (object)[
|
||||
"id" => (int) $usrs[$i],
|
||||
"first_name" => "DELETED",
|
||||
"last_name" => "",
|
||||
"deactivated" => "deleted"
|
||||
];
|
||||
} else if($usrs[$i] == NULL) {
|
||||
if($usrs[$i] != 0) {
|
||||
$usr = $users->get((int) $usrs[$i]);
|
||||
if(is_null($usr) || $usr->isDeleted()) {
|
||||
$response[$i] = (object)[
|
||||
"id" => (int) $usrs[$i],
|
||||
"first_name" => "DELETED",
|
||||
"last_name" => "",
|
||||
"deactivated" => "deleted"
|
||||
];
|
||||
} else if($usrs[$i] == NULL) {
|
||||
|
||||
} else {
|
||||
$response[$i] = (object)[
|
||||
"id" => $usr->getId(),
|
||||
"first_name" => $usr->getFirstName(),
|
||||
"last_name" => $usr->getLastName(),
|
||||
"is_closed" => false,
|
||||
"can_access_closed" => true,
|
||||
];
|
||||
} else {
|
||||
$response[$i] = (object)[
|
||||
"id" => $usr->getId(),
|
||||
"first_name" => $usr->getFirstName(),
|
||||
"last_name" => $usr->getLastName(),
|
||||
"is_closed" => false,
|
||||
"can_access_closed" => true,
|
||||
];
|
||||
|
||||
$flds = explode(',', $fields);
|
||||
$flds = explode(',', $fields);
|
||||
|
||||
foreach($flds as $field) {
|
||||
switch($field) {
|
||||
case "verified":
|
||||
$response[$i]->verified = intval($usr->isVerified());
|
||||
break;
|
||||
case "sex":
|
||||
$response[$i]->sex = $usr->isFemale() ? 1 : 2;
|
||||
break;
|
||||
case "has_photo":
|
||||
$response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1;
|
||||
break;
|
||||
case "photo_max_orig":
|
||||
$response[$i]->photo_max_orig = $usr->getAvatarURL();
|
||||
break;
|
||||
case "photo_max":
|
||||
$response[$i]->photo_max = $usr->getAvatarURL("original");
|
||||
break;
|
||||
case "photo_50":
|
||||
$response[$i]->photo_50 = $usr->getAvatarURL();
|
||||
break;
|
||||
case "photo_100":
|
||||
$response[$i]->photo_100 = $usr->getAvatarURL("tiny");
|
||||
break;
|
||||
case "photo_200":
|
||||
$response[$i]->photo_200 = $usr->getAvatarURL("normal");
|
||||
break;
|
||||
case "photo_200_orig": # вообще не ебу к чему эта строка ну пусть будет кек
|
||||
$response[$i]->photo_200_orig = $usr->getAvatarURL("normal");
|
||||
break;
|
||||
case "photo_400_orig":
|
||||
$response[$i]->photo_400_orig = $usr->getAvatarURL("normal");
|
||||
break;
|
||||
|
||||
# Она хочет быть выебанной видя матан
|
||||
# Покайфу когда ты Виет а вокруг лишь дискриминант
|
||||
case "status":
|
||||
if($usr->getStatus() != NULL)
|
||||
$response[$i]->status = $usr->getStatus();
|
||||
break;
|
||||
case "screen_name":
|
||||
if($usr->getShortCode() != NULL)
|
||||
$response[$i]->screen_name = $usr->getShortCode();
|
||||
break;
|
||||
case "friend_status":
|
||||
switch($usr->getSubscriptionStatus($authuser)) {
|
||||
case 3:
|
||||
# NOTICE falling through
|
||||
case 0:
|
||||
$response[$i]->friend_status = $usr->getSubscriptionStatus($authuser);
|
||||
break;
|
||||
case 1:
|
||||
$response[$i]->friend_status = 2;
|
||||
break;
|
||||
case 2:
|
||||
$response[$i]->friend_status = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "last_seen":
|
||||
if ($usr->onlineStatus() == 0)
|
||||
$response[$i]->last_seen = (object) [
|
||||
"platform" => 1,
|
||||
"time" => $usr->getOnline()->timestamp()
|
||||
];
|
||||
case "music":
|
||||
$response[$i]->music = $usr->getFavoriteMusic();
|
||||
break;
|
||||
case "movies":
|
||||
$response[$i]->movies = $usr->getFavoriteFilms();
|
||||
break;
|
||||
case "tv":
|
||||
$response[$i]->tv = $usr->getFavoriteShows();
|
||||
break;
|
||||
case "books":
|
||||
$response[$i]->books = $usr->getFavoriteBooks();
|
||||
break;
|
||||
case "city":
|
||||
$response[$i]->city = $usr->getCity();
|
||||
break;
|
||||
case "interests":
|
||||
$response[$i]->interests = $usr->getInterests();
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach($flds as $field) {
|
||||
switch($field) {
|
||||
case "verified":
|
||||
$response[$i]->verified = intval($usr->isVerified());
|
||||
break;
|
||||
case "sex":
|
||||
$response[$i]->sex = $usr->isFemale() ? 1 : 2;
|
||||
break;
|
||||
case "has_photo":
|
||||
$response[$i]->has_photo = is_null($usr->getAvatarPhoto()) ? 0 : 1;
|
||||
break;
|
||||
case "photo_max_orig":
|
||||
$response[$i]->photo_max_orig = $usr->getAvatarURL();
|
||||
break;
|
||||
case "photo_max":
|
||||
$response[$i]->photo_max = $usr->getAvatarURL("original");
|
||||
break;
|
||||
case "photo_50":
|
||||
$response[$i]->photo_50 = $usr->getAvatarURL();
|
||||
break;
|
||||
case "photo_100":
|
||||
$response[$i]->photo_100 = $usr->getAvatarURL("tiny");
|
||||
break;
|
||||
case "photo_200":
|
||||
$response[$i]->photo_200 = $usr->getAvatarURL("normal");
|
||||
break;
|
||||
case "photo_200_orig": # вообще не ебу к чему эта строка ну пусть будет кек
|
||||
$response[$i]->photo_200_orig = $usr->getAvatarURL("normal");
|
||||
break;
|
||||
case "photo_400_orig":
|
||||
$response[$i]->photo_400_orig = $usr->getAvatarURL("normal");
|
||||
break;
|
||||
|
||||
# Она хочет быть выебанной видя матан
|
||||
# Покайфу когда ты Виет а вокруг лишь дискриминант
|
||||
|
||||
if($usr->getOnline()->timestamp() + 300 > time())
|
||||
$response[$i]->online = 1;
|
||||
else
|
||||
$response[$i]->online = 0;
|
||||
}
|
||||
# ору а когда я это успел написать
|
||||
# вова кстати не матерись в коде мамка же спалит азщазаззазщазазаззазазазх
|
||||
case "status":
|
||||
if($usr->getStatus() != NULL)
|
||||
$response[$i]->status = $usr->getStatus();
|
||||
break;
|
||||
case "screen_name":
|
||||
if($usr->getShortCode() != NULL)
|
||||
$response[$i]->screen_name = $usr->getShortCode();
|
||||
break;
|
||||
case "friend_status":
|
||||
switch($usr->getSubscriptionStatus($authuser)) {
|
||||
case 3:
|
||||
# NOTICE falling through
|
||||
case 0:
|
||||
$response[$i]->friend_status = $usr->getSubscriptionStatus($authuser);
|
||||
break;
|
||||
case 1:
|
||||
$response[$i]->friend_status = 2;
|
||||
break;
|
||||
case 2:
|
||||
$response[$i]->friend_status = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "last_seen":
|
||||
if ($usr->onlineStatus() == 0)
|
||||
$response[$i]->last_seen = (object) [
|
||||
"platform" => 1,
|
||||
"time" => $usr->getOnline()->timestamp()
|
||||
];
|
||||
case "music":
|
||||
$response[$i]->music = $usr->getFavoriteMusic();
|
||||
break;
|
||||
case "movies":
|
||||
$response[$i]->movies = $usr->getFavoriteFilms();
|
||||
break;
|
||||
case "tv":
|
||||
$response[$i]->tv = $usr->getFavoriteShows();
|
||||
break;
|
||||
case "books":
|
||||
$response[$i]->books = $usr->getFavoriteBooks();
|
||||
break;
|
||||
case "city":
|
||||
$response[$i]->city = $usr->getCity();
|
||||
break;
|
||||
case "interests":
|
||||
$response[$i]->interests = $usr->getInterests();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($usr->getOnline()->timestamp() + 300 > time())
|
||||
$response[$i]->online = 1;
|
||||
else
|
||||
$response[$i]->online = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
|
|
49
Web/Models/Entities/BannedLink.php
Normal file
49
Web/Models/Entities/BannedLink.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Entities;
|
||||
use openvk\Web\Models\RowModel;
|
||||
use openvk\Web\Models\Entities\{User};
|
||||
use openvk\Web\Models\Repositories\{Users};
|
||||
use Nette\Database\Table\ActiveRow;
|
||||
|
||||
class BannedLink extends RowModel
|
||||
{
|
||||
protected $tableName = "links_banned";
|
||||
private $overrideContentColumn = "reason";
|
||||
|
||||
function getId(): int
|
||||
{
|
||||
return $this->getRecord()->id;
|
||||
}
|
||||
|
||||
function getDomain(): string
|
||||
{
|
||||
return $this->getRecord()->domain;
|
||||
}
|
||||
|
||||
function getReason(): string
|
||||
{
|
||||
return $this->getRecord()->reason ?? tr("url_is_banned_default_reason");
|
||||
}
|
||||
|
||||
function getInitiator(): ?User
|
||||
{
|
||||
return (new Users)->get($this->getRecord()->initiator);
|
||||
}
|
||||
|
||||
function getComment(): string
|
||||
{
|
||||
return OPENVK_ROOT_CONF["openvk"]["preferences"]["susLinks"]["showReason"]
|
||||
? tr("url_is_banned_comment_r", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"], $this->getReason())
|
||||
: tr("url_is_banned_comment", OPENVK_ROOT_CONF["openvk"]["appearance"]["name"]);
|
||||
}
|
||||
|
||||
function getRegexpRule(): string
|
||||
{
|
||||
return addslashes("/" . $this->getDomain() . $this->getRawRegexp() . "/");
|
||||
}
|
||||
|
||||
function getRawRegexp(): string
|
||||
{
|
||||
return $this->getRecord()->regexp_rule;
|
||||
}
|
||||
}
|
|
@ -35,12 +35,12 @@ trait TRichText
|
|||
"%(([A-z]++):\/\/(\S*?\.\S*?))([\s)\[\]{},\"\'<]|\.\s|$)%",
|
||||
(function (array $matches): string {
|
||||
$href = str_replace("#", "#", $matches[1]);
|
||||
$href = str_replace(";", ";", $matches[1]);
|
||||
$href = rawurlencode(str_replace(";", ";", $matches[1]));
|
||||
$link = str_replace("#", "#", $matches[3]);
|
||||
$link = str_replace(";", ";", $matches[3]);
|
||||
$rel = $this->isAd() ? "sponsored" : "ugc";
|
||||
|
||||
return "<a href='$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]);
|
||||
}),
|
||||
$text
|
||||
);
|
||||
|
|
|
@ -768,7 +768,7 @@ class User extends RowModel
|
|||
]);
|
||||
}
|
||||
|
||||
function ban(string $reason, bool $deleteSubscriptions = true): void
|
||||
function ban(string $reason, bool $deleteSubscriptions = true, ?int $unban_time = NULL): void
|
||||
{
|
||||
if($deleteSubscriptions) {
|
||||
$subs = DatabaseConnection::i()->getContext()->table("subscriptions");
|
||||
|
@ -782,6 +782,7 @@ class User extends RowModel
|
|||
}
|
||||
|
||||
$this->setBlock_Reason($reason);
|
||||
$this->setUnblock_time($unban_time);
|
||||
$this->save();
|
||||
}
|
||||
|
||||
|
@ -1012,26 +1013,42 @@ class User extends RowModel
|
|||
return $this->getRecord()->website;
|
||||
}
|
||||
|
||||
# ты устрица
|
||||
function isActivated(): bool
|
||||
{
|
||||
return (bool) $this->getRecord()->activated;
|
||||
}
|
||||
# ты устрица
|
||||
function isActivated(): bool
|
||||
{
|
||||
return (bool) $this->getRecord()->activated;
|
||||
}
|
||||
|
||||
function isBtModerator(): bool
|
||||
{
|
||||
return $this->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL);
|
||||
}
|
||||
function isBtModerator(): bool
|
||||
{
|
||||
return $this->getChandlerUser()->can("admin")->model('openvk\Web\Models\Repositories\BugtrackerReports')->whichBelongsTo(NULL);
|
||||
}
|
||||
|
||||
function getBanInBtReason(): ?string
|
||||
{
|
||||
return $this->getRecord()->block_in_bt_reason;
|
||||
}
|
||||
function getBanInBtReason(): ?string
|
||||
{
|
||||
return $this->getRecord()->block_in_bt_reason;
|
||||
}
|
||||
|
||||
function isBannedInBt(): bool
|
||||
{
|
||||
return !is_null($this->getBanInBtReason());
|
||||
}
|
||||
function isBannedInBt(): bool
|
||||
{
|
||||
return !is_null($this->getBanInBtReason());
|
||||
}
|
||||
|
||||
function getUnbanTime(): ?string
|
||||
{
|
||||
return !is_null($this->getRecord()->unblock_time) ? date('d.m.Y', $this->getRecord()->unblock_time) : NULL;
|
||||
}
|
||||
|
||||
function canUnbanThemself(): bool
|
||||
{
|
||||
if (!$this->isBanned())
|
||||
return false;
|
||||
|
||||
if ($this->getRecord()->unblock_time > time() || $this->getRecord()->unblock_time == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
use Traits\TSubscribable;
|
||||
use Traits\TSubscribable;
|
||||
}
|
||||
|
|
73
Web/Models/Repositories/BannedLinks.php
Normal file
73
Web/Models/Repositories/BannedLinks.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Repositories;
|
||||
use Chandler\Database\DatabaseConnection as DB;
|
||||
use Nette\Database\Table\{ActiveRow, Selection};
|
||||
use openvk\Web\Models\Entities\BannedLink;
|
||||
|
||||
class BannedLinks
|
||||
{
|
||||
private $context;
|
||||
private $bannedLinks;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->context = DB::i()->getContext();
|
||||
$this->bannedLinks = $this->context->table("links_banned");
|
||||
}
|
||||
|
||||
function toBannedLink(?ActiveRow $ar): ?BannedLink
|
||||
{
|
||||
return is_null($ar) ? NULL : new BannedLink($ar);
|
||||
}
|
||||
|
||||
function get(int $id): ?BannedLink
|
||||
{
|
||||
return $this->toBannedLink($this->bannedLinks->get($id));
|
||||
}
|
||||
|
||||
function getList(?int $page = 1): \Traversable
|
||||
{
|
||||
foreach($this->bannedLinks->order("id DESC")->page($page, OPENVK_DEFAULT_PER_PAGE) as $link)
|
||||
yield new BannedLink($link);
|
||||
}
|
||||
|
||||
function getCount(int $page = 1): int
|
||||
{
|
||||
return sizeof($this->bannedLinks->fetch());
|
||||
}
|
||||
|
||||
function getByDomain(string $domain): ?Selection
|
||||
{
|
||||
return $this->bannedLinks->where("domain", $domain);
|
||||
}
|
||||
|
||||
function isDomainBanned(string $domain): bool
|
||||
{
|
||||
return sizeof($this->bannedLinks->where(["link" => $domain, "regexp_rule" => ""])) > 0;
|
||||
}
|
||||
|
||||
function genLinks($rules): \Traversable
|
||||
{
|
||||
foreach ($rules as $rule)
|
||||
yield $this->get($rule->id);
|
||||
}
|
||||
|
||||
function genEntries($links, $uri): \Traversable
|
||||
{
|
||||
foreach($links as $link)
|
||||
if (preg_match($link->getRegexpRule(), $uri))
|
||||
yield $link->getId();
|
||||
}
|
||||
|
||||
function check(string $url): ?array
|
||||
{
|
||||
$uri = strstr(str_replace(["https://", "http://"], "", $url), "/", true);
|
||||
$domain = str_replace("www.", "", $uri);
|
||||
$rules = $this->getByDomain($domain);
|
||||
|
||||
if (is_null($rules))
|
||||
return NULL;
|
||||
|
||||
return iterator_to_array($this->genEntries($this->genLinks($rules), $uri));
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Presenters;
|
||||
use openvk\Web\Models\Entities\{Voucher, Gift, GiftCategory, User};
|
||||
use openvk\Web\Models\Repositories\{Users, Clubs, Vouchers, Gifts};
|
||||
use openvk\Web\Models\Entities\{Voucher, Gift, GiftCategory, User, BannedLink};
|
||||
use openvk\Web\Models\Repositories\{Users, Clubs, Vouchers, Gifts, BannedLinks};
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
|
||||
final class AdminPresenter extends OpenVKPresenter
|
||||
{
|
||||
|
@ -9,13 +10,15 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
private $clubs;
|
||||
private $vouchers;
|
||||
private $gifts;
|
||||
private $bannedLinks;
|
||||
|
||||
function __construct(Users $users, Clubs $clubs, Vouchers $vouchers, Gifts $gifts)
|
||||
function __construct(Users $users, Clubs $clubs, Vouchers $vouchers, Gifts $gifts, BannedLinks $bannedLinks)
|
||||
{
|
||||
$this->users = $users;
|
||||
$this->clubs = $clubs;
|
||||
$this->vouchers = $vouchers;
|
||||
$this->gifts = $gifts;
|
||||
$this->bannedLinks = $bannedLinks;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
@ -339,12 +342,14 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
function renderQuickBan(int $id): void
|
||||
{
|
||||
$this->assertNoCSRF();
|
||||
|
||||
|
||||
$unban_time = strtotime($this->queryParam("date")) ?: NULL;
|
||||
|
||||
$user = $this->users->get($id);
|
||||
if(!$user)
|
||||
exit(json_encode([ "error" => "User does not exist" ]));
|
||||
|
||||
$user->ban($this->queryParam("reason"));
|
||||
$user->ban($this->queryParam("reason"), true, $unban_time);
|
||||
exit(json_encode([ "success" => true, "reason" => $this->queryParam("reason") ]));
|
||||
}
|
||||
|
||||
|
@ -356,7 +361,8 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
if(!$user)
|
||||
exit(json_encode([ "error" => "User does not exist" ]));
|
||||
|
||||
$user->setBlock_Reason(null);
|
||||
$user->setBlock_Reason(NULL);
|
||||
$user->setUnblock_time(NULL);
|
||||
$user->save();
|
||||
exit(json_encode([ "success" => true ]));
|
||||
}
|
||||
|
@ -372,4 +378,73 @@ final class AdminPresenter extends OpenVKPresenter
|
|||
$user->adminNotify("⚠️ " . $this->queryParam("message"));
|
||||
exit(json_encode([ "message" => $this->queryParam("message") ]));
|
||||
}
|
||||
|
||||
function renderBannedLinks(): void
|
||||
{
|
||||
$this->template->links = $this->bannedLinks->getList((int) $this->queryParam("p") ?: 1);
|
||||
$this->template->users = new Users;
|
||||
}
|
||||
|
||||
function renderBannedLink(int $id): void
|
||||
{
|
||||
$this->template->form = (object) [];
|
||||
|
||||
if($id === 0) {
|
||||
$this->template->form->id = 0;
|
||||
$this->template->form->link = NULL;
|
||||
$this->template->form->reason = NULL;
|
||||
} else {
|
||||
$link = (new BannedLinks)->get($id);
|
||||
if(!$link)
|
||||
$this->notFound();
|
||||
|
||||
$this->template->form->id = $link->getId();
|
||||
$this->template->form->link = $link->getDomain();
|
||||
$this->template->form->reason = $link->getReason();
|
||||
$this->template->form->regexp = $link->getRawRegexp();
|
||||
}
|
||||
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST")
|
||||
return;
|
||||
|
||||
$link = (new BannedLinks)->get($id);
|
||||
|
||||
$new_domain = parse_url($this->postParam("link"))["host"];
|
||||
$new_reason = $this->postParam("reason") ?: NULL;
|
||||
|
||||
$lid = $id;
|
||||
|
||||
if ($link) {
|
||||
$link->setDomain($new_domain ?? $this->postParam("link"));
|
||||
$link->setReason($new_reason);
|
||||
$link->setRegexp_rule($this->postParam("regexp"));
|
||||
$link->save();
|
||||
} else {
|
||||
if (!$new_domain)
|
||||
$this->flashFail("err", tr("error"), tr("admin_banned_link_not_specified"));
|
||||
|
||||
$link = new BannedLink;
|
||||
$link->setDomain($new_domain);
|
||||
$link->setReason($new_reason);
|
||||
$link->setRegexp_rule($this->postParam("regexp"));
|
||||
$link->setInitiator($this->user->identity->getId());
|
||||
$link->save();
|
||||
|
||||
$lid = $link->getId();
|
||||
}
|
||||
|
||||
$this->redirect("/admin/bannedLink/id" . $lid);
|
||||
}
|
||||
|
||||
function renderUnbanLink(int $id): void
|
||||
{
|
||||
$link = (new BannedLinks)->get($id);
|
||||
|
||||
if (!$link)
|
||||
$this->flashFail("err", tr("error"), tr("admin_banned_link_not_found"));
|
||||
|
||||
$link->delete(false);
|
||||
|
||||
$this->redirect("/admin/bannedLinks");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -322,4 +322,39 @@ final class AuthPresenter extends OpenVKPresenter
|
|||
|
||||
$this->redirect("/");
|
||||
}
|
||||
|
||||
function renderUnbanThemself(): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
if(!$this->user->identity->canUnbanThemself())
|
||||
$this->flashFail("err", tr("error"), tr("forbidden"));
|
||||
|
||||
$user = $this->users->get($this->user->id);
|
||||
|
||||
$user->setBlock_Reason(NULL);
|
||||
$user->setUnblock_Time(NULL);
|
||||
$user->save();
|
||||
|
||||
$this->flashFail("succ", tr("banned_unban_title"), tr("banned_unban_description"));
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will revoke all tokens, including API and Web tokens and except active one
|
||||
*
|
||||
* OF COURSE it requires CSRF
|
||||
*/
|
||||
function renderRevokeAllTokens(): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
$this->assertNoCSRF();
|
||||
|
||||
// API tokens
|
||||
$this->db->table("api_tokens")->where("user", $this->user->identity->getId())->delete();
|
||||
// Web tokens
|
||||
$this->db->table("ChandlerTokens")->where("user", $this->user->identity->getChandlerGUID())->where("token != ?", Session::i()->get("tok"))->delete();
|
||||
$this->flashFail("succ", tr("information_-1"), tr("end_all_sessions_done"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Presenters;
|
||||
use openvk\Web\Models\Repositories\BannedLinks;
|
||||
use openvk\Web\Models\Entities\BannedLink;
|
||||
|
||||
final class AwayPresenter extends OpenVKPresenter
|
||||
{
|
||||
function renderAway(): void
|
||||
{
|
||||
$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]);
|
||||
|
||||
header("HTTP/1.0 302 Found");
|
||||
header("X-Robots-Tag: noindex, nofollow, noarchive");
|
||||
header("Location: " . $this->queryParam("to"));
|
||||
exit;
|
||||
}
|
||||
|
||||
function renderView(int $lid) {
|
||||
$this->template->link = (new BannedLinks)->get($lid);
|
||||
|
||||
if (!$this->template->link)
|
||||
$this->notFound();
|
||||
|
||||
$this->template->to = $this->queryParam("to");
|
||||
}
|
||||
}
|
||||
|
|
13
Web/Presenters/BannedLinkPresenter.php
Normal file
13
Web/Presenters/BannedLinkPresenter.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Presenters;
|
||||
|
||||
use openvk\Web\Models\Entities\BannedLink;
|
||||
use openvk\Web\Models\Repositories\BannedLinks;
|
||||
|
||||
final class BannedLinkPresenter extends OpenVKPresenter
|
||||
{
|
||||
function renderView(int $lid) {
|
||||
$this->template->link = (new BannedLinks)->get($lid);
|
||||
$this->template->to = $this->queryParam("to");
|
||||
}
|
||||
}
|
|
@ -29,9 +29,10 @@ final class InternalAPIPresenter extends OpenVKPresenter
|
|||
|
||||
function renderRoute(): void
|
||||
{
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST")
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST") {
|
||||
header("HTTP/1.1 405 Method Not Allowed");
|
||||
exit("ты дебил это точка апи");
|
||||
|
||||
}
|
||||
try {
|
||||
$input = (object) MessagePack::unpack(file_get_contents("php://input"));
|
||||
} catch (\Exception $ex) {
|
||||
|
@ -71,9 +72,10 @@ final class InternalAPIPresenter extends OpenVKPresenter
|
|||
}
|
||||
|
||||
function renderTimezone() {
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST")
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST") {
|
||||
header("HTTP/1.1 405 Method Not Allowed");
|
||||
exit("ты дебил это метод апи");
|
||||
|
||||
}
|
||||
$sessionOffset = Session::i()->get("_timezoneOffset");
|
||||
if(is_numeric($this->postParam("timezone", false))) {
|
||||
$postTZ = intval($this->postParam("timezone", false));
|
||||
|
|
|
@ -17,7 +17,6 @@ final class UserPresenter extends OpenVKPresenter
|
|||
private $users;
|
||||
|
||||
public $deactivationTolerant = false;
|
||||
|
||||
function __construct(Users $users)
|
||||
{
|
||||
$this->users = $users;
|
||||
|
@ -454,7 +453,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$this->flash("succ", tr("changes_saved"), tr("changes_saved_comment"));
|
||||
}
|
||||
$this->template->mode = in_array($this->queryParam("act"), [
|
||||
"main", "privacy", "finance", "finance.top-up", "interface"
|
||||
"main", "security", "privacy", "finance", "finance.top-up", "interface"
|
||||
]) ? $this->queryParam("act")
|
||||
: "main";
|
||||
|
||||
|
|
|
@ -113,14 +113,14 @@ final class WallPresenter extends OpenVKPresenter
|
|||
$feed = new Feed();
|
||||
|
||||
$channel = new Channel();
|
||||
$channel->title($post->getOwner()->getCanonicalName() . " — " . OPENVK_ROOT_CONF['openvk']['appearance']['name'])->url(ovk_scheme(true) . $_SERVER["SERVER_NAME"])->appendTo($feed);
|
||||
$channel->title($owner->getCanonicalName() . " — " . OPENVK_ROOT_CONF['openvk']['appearance']['name'])->url(ovk_scheme(true) . $_SERVER["HTTP_HOST"])->appendTo($feed);
|
||||
|
||||
foreach($posts as $post) {
|
||||
$item = new Item();
|
||||
$item
|
||||
->title($post->getOwner()->getCanonicalName())
|
||||
->description($post->getText())
|
||||
->url(ovk_scheme(true).$_SERVER["SERVER_NAME"]."/wall{$post->getPrettyId()}")
|
||||
->url(ovk_scheme(true).$_SERVER["HTTP_HOST"]."/wall{$post->getPrettyId()}")
|
||||
->pubDate($post->getPublicationTime()->timestamp())
|
||||
->appendTo($channel);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,16 @@
|
|||
<p>
|
||||
{tr("banned_1", htmlentities($thisUser->getCanonicalName()))|noescape}<br/>
|
||||
{tr("banned_2", htmlentities($thisUser->getBanReason()))|noescape}
|
||||
|
||||
{if !$thisUser->getUnbanTime()}
|
||||
{_banned_perm}
|
||||
{else}
|
||||
{tr("banned_until_time", $thisUser->getUnbanTime())|noescape}
|
||||
{/if}
|
||||
</p>
|
||||
<p n:if="$thisUser->canUnbanThemself()">
|
||||
<hr/>
|
||||
<center><a class="button" href="/unban.php">{_banned_unban_myself}</a></center>
|
||||
</p>
|
||||
<hr/>
|
||||
<p>
|
||||
|
|
|
@ -396,8 +396,8 @@
|
|||
<tr>
|
||||
<td class="e">
|
||||
Vladimir Barinov (veselcraft), Celestora, Konstantin Kichulkin (kosfurler),
|
||||
Nikita Volkov (sup_ban), Daniel Myslivets, Alexander Kotov (l-lacker),
|
||||
Alexey Assemblerov (BiosNod), Ilya Prokopenko (dsrev) and Maxim Leshchenko (maksales / maksalees)
|
||||
Nikita Volkov (sup_ban), Daniel Myslivets, Maxim Leshchenko (maksales / maksalees)
|
||||
and n1rwana
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
<li>
|
||||
<a href="/admin/clubs">{_groups}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/bannedLinks">{_admin_banned_links}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="aui-nav-heading">
|
||||
<strong>{_admin_services}</strong>
|
||||
|
|
48
Web/Presenters/templates/Admin/BannedLink.xml
Normal file
48
Web/Presenters/templates/Admin/BannedLink.xml
Normal file
|
@ -0,0 +1,48 @@
|
|||
{extends "@layout.xml"}
|
||||
|
||||
{block title}
|
||||
{_edit}
|
||||
{/block}
|
||||
|
||||
{block heading}
|
||||
{_edit} #{$form->id ?? "undefined"}
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<div style="margin: 8px -8px;" class="aui-tabs horizontal-tabs">
|
||||
<ul class="tabs-menu">
|
||||
<li class="menu-item active-tab">
|
||||
<a href="#info">{_admin_banned_link}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tabs-pane active-pane" id="info">
|
||||
<form class="aui" method="POST">
|
||||
<div class="field-group">
|
||||
<label for="id">ID</label>
|
||||
<input class="text long-field" type="number" id="id" name="id" disabled value="{$form->id}" />
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<label for="token">{_admin_banned_domain}</label>
|
||||
<input class="text long-field" type="text" id="link" name="link" value="{$form->link}" />
|
||||
<div class="description">{_admin_banned_link_description}</div>
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<label for="token">{_admin_banned_link_regexp}</label>
|
||||
<input class="text long-field" type="text" id="regexp" name="regexp" value="{$form->regexp}" />
|
||||
<div class="description">{_admin_banned_link_regexp_description}</div>
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<label for="coins">{_admin_banned_link_reason}</label>
|
||||
<input class="text long-field" type="text" id="reason" name="reason" value="{$form->reason}" />
|
||||
</div>
|
||||
<div class="buttons-container">
|
||||
<div class="buttons">
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input class="aui-button aui-button-primary submit" type="submit" value="{_save}">
|
||||
<a class="aui-button aui-button-secondary" href="/admin/bannedLink/id{$form->id}/unban">{_delete}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
46
Web/Presenters/templates/Admin/BannedLinks.xml
Normal file
46
Web/Presenters/templates/Admin/BannedLinks.xml
Normal file
|
@ -0,0 +1,46 @@
|
|||
{extends "@layout.xml"}
|
||||
|
||||
{block title}
|
||||
{_admin_banned_links}
|
||||
{/block}
|
||||
|
||||
{block heading}
|
||||
<a style="float: right;" class="aui-button aui-button-primary" href="/admin/bannedLink/id0">
|
||||
{_create}
|
||||
</a>
|
||||
|
||||
{_admin_banned_links}
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<table class="aui aui-table-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>{_admin_banned_domain}</th>
|
||||
<th>REGEXP</th>
|
||||
<th>{_admin_banned_link_reason}</th>
|
||||
<th>{_admin_banned_link_initiator}</th>
|
||||
<th>{_admin_actions}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr n:foreach="$links as $link">
|
||||
<td>{$link->getId()}</td>
|
||||
<td>{$link->getDomain()}</td>
|
||||
<td>{$link->getRegexpRule()}</td>
|
||||
<td>{$link->getReason() ?? "-"}</td>
|
||||
<td>{$link->getInitiator()->getCanonicalName()}</td>
|
||||
<td>
|
||||
<a class="aui-button aui-button-primary" href="/admin/bannedLink/id{$link->getId()}">
|
||||
<span class="aui-icon aui-icon-small aui-iconfont-new-edit">{_edit}</span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div align="right">
|
||||
<a n:if="($_GET['p'] ?? 1) > 1" class="aui-button" href="?p={($_GET['p'] ?? 1) - 1}">«</a>
|
||||
<a class="aui-button" href="?p={($_GET['p'] ?? 1) + 1}">»</a>
|
||||
</div>
|
||||
{/block}
|
22
Web/Presenters/templates/Away/View.xml
Normal file
22
Web/Presenters/templates/Away/View.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
{extends "../@layout.xml"}
|
||||
|
||||
{block title}Переход по ссылке заблокирован{/block}
|
||||
|
||||
{block header}
|
||||
Предупреждение
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<div style="min-height: 120px;">
|
||||
<img src="/assets/packages/static/openvk/img/oof.apng" width="110" height="110" style="margin-left: 20px;">
|
||||
|
||||
<div style="padding-left: 150px; margin-top: -100px;">
|
||||
<h4 style="font-size: 14px; margin-bottom: 8px;">{_url_is_banned_title}</h4>
|
||||
<span>
|
||||
{$link->getComment()|noescape}
|
||||
</span>
|
||||
<br><br>
|
||||
<a href="{$to}" class="button" target="_blank">{_url_is_banned_proceed}</a>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
|
@ -1,4 +1,4 @@
|
|||
{extends "../@listView.xml"}
|
||||
{extends "../@layout.xml"}
|
||||
{var $sorting = false}
|
||||
|
||||
{block title}
|
||||
|
@ -10,29 +10,47 @@
|
|||
{_feedback}
|
||||
{/block}
|
||||
|
||||
{block tabs}
|
||||
{block content}
|
||||
<div n:ifcontent class="tabs">
|
||||
<div n:attr="id => ($mode === 'new' ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($mode === 'new' ? 'act_tab_a' : 'ki')" href="?act=new">{_unread}</a>
|
||||
</div>
|
||||
<div n:attr="id => ($mode === 'archived' ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($mode === 'archived' ? 'act_tab_a' : 'ki')" href="?act=archived">{_archive}</a>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{* BEGIN ELEMENTS DESCRIPTION *}
|
||||
|
||||
{block link|strip|stripHtml}
|
||||
javascript:void(0)
|
||||
{/block}
|
||||
|
||||
{block preview}
|
||||
<img src="{$x->getModel(1)->getAvatarUrl('miniscule')}" width=64 />
|
||||
{/block}
|
||||
|
||||
{block name}
|
||||
<span style="color: #000; font-weight: 100;"></span>
|
||||
{/block}
|
||||
|
||||
{block description}
|
||||
{include $x->getTemplatePath(), notification => $x}
|
||||
{/block}
|
||||
</div>
|
||||
{var $data = is_array($iterator) ? $iterator : iterator_to_array($iterator)}
|
||||
{if sizeof($data) > 0}
|
||||
<table class="post post-divider" border="0" style="font-size: 11px;" n:foreach="$data as $dat">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="54" valign="top">
|
||||
<a href="/sysop">
|
||||
<img src="{$dat->getModel(1)->getAvatarUrl('miniscule')}" width=50 />
|
||||
</a>
|
||||
</td>
|
||||
<td width="100%" valign="top">
|
||||
<div class="post-content">
|
||||
<div class="text" style="line-height: 12pt;">
|
||||
{include $dat->getTemplatePath(), notification => $dat}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{include "../components/paginator.xml", conf => (object) [
|
||||
"page" => $page,
|
||||
"count" => $count,
|
||||
"amount" => sizeof($data),
|
||||
"perPage" => $perPage ?? OPENVK_DEFAULT_PER_PAGE,
|
||||
"atBottom" => true,
|
||||
]}
|
||||
{else}
|
||||
{ifset customErrorMessage}
|
||||
{include customErrorMessage}
|
||||
{else}
|
||||
{include "../components/nothing.xml"}
|
||||
{/ifset}
|
||||
{/if}
|
||||
{/block}
|
|
@ -8,6 +8,7 @@
|
|||
{block content}
|
||||
|
||||
{var $isMain = $mode === 'main'}
|
||||
{var $isSecurity = $mode === 'security'}
|
||||
{var $isPrivacy = $mode === 'privacy'}
|
||||
{var $isFinance = $mode === 'finance'}
|
||||
{var $isFinanceTU = $mode === 'finance.top-up'}
|
||||
|
@ -17,6 +18,9 @@
|
|||
<div n:attr="id => ($isMain ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($isMain ? 'act_tab_a' : 'ki')" href="/settings">{_main}</a>
|
||||
</div>
|
||||
<div n:attr="id => ($isSecurity ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($isSecurity ? 'act_tab_a' : 'ki')" href="/settings?act=security">{_security}</a>
|
||||
</div>
|
||||
<div n:attr="id => ($isPrivacy ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($isPrivacy ? 'act_tab_a' : 'ki')" href="/settings?act=privacy">{_privacy}</a>
|
||||
</div>
|
||||
|
@ -30,7 +34,92 @@
|
|||
|
||||
<div class="container_gray">
|
||||
{if $isMain}
|
||||
|
||||
|
||||
<form action="/settings?act=main" method="POST" enctype="multipart/form-data">
|
||||
<h4>{_your_email_address}</h4>
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_current_email_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
{$user->getEmail()}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_new_email_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="email" name="new_email" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_password}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" name="email_change_pass" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr n:if="$user->is2faEnabled()">
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_"2fa_code"}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="email_change_code" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<input type="submit" value="{_save_email_address}" class="button" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<h4>{_your_page_address}</h4>
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_page_id}</span>
|
||||
</td>
|
||||
<td>
|
||||
{$user->getId()}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_page_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="sc" value="{$user->getShortCode()}" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" value="{_save}" class="button" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<br/>
|
||||
<div class="settings_delete">
|
||||
{_you_can_also} <a onClick="showProfileDeactivateDialog({$csrfToken})">{_delete_your_page}</a>.
|
||||
</div>
|
||||
|
||||
{elseif $isSecurity}
|
||||
<form action="/settings?act=main" method="POST" enctype="multipart/form-data">
|
||||
<h4>{_change_password}</h4>
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
|
@ -69,7 +158,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
|
@ -79,153 +168,92 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<h4>{_two_factor_authentication}</h4>
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
<tbody>
|
||||
{if $user->is2faEnabled()}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="accent-box">
|
||||
{_two_factor_authentication_enabled}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a class="button" href="javascript:viewBackupCodes()">{_view_backup_codes}</a>
|
||||
<a class="button" href="javascript:disableTwoFactorAuth()">{_disable}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<br/>
|
||||
<h4>{_two_factor_authentication}</h4>
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
<tbody>
|
||||
{if $user->is2faEnabled()}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="accent-box">
|
||||
{_two_factor_authentication_enabled}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a class="button" href="javascript:viewBackupCodes()">{_view_backup_codes}</a>
|
||||
<a class="button" href="javascript:disableTwoFactorAuth()">{_disable}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<script>
|
||||
function viewBackupCodes() {
|
||||
MessageBox("Просмотр резервных кодов", `
|
||||
<form id="back-codes-view-form" method="post" action="/settings/2fa">
|
||||
<label for="password">Пароль</label>
|
||||
<input type="password" id="password" name="password" required />
|
||||
<input type="hidden" name="hash" value={$csrfToken} />
|
||||
</form>
|
||||
`, ["Просмотреть", "Отменить"], [
|
||||
() => {
|
||||
document.querySelector("#back-codes-view-form").submit();
|
||||
}, Function.noop
|
||||
]);
|
||||
}
|
||||
<script>
|
||||
function viewBackupCodes() {
|
||||
MessageBox("Просмотр резервных кодов", `
|
||||
<form id="back-codes-view-form" method="post" action="/settings/2fa">
|
||||
<label for="password">Пароль</label>
|
||||
<input type="password" id="password" name="password" required />
|
||||
<input type="hidden" name="hash" value={$csrfToken} />
|
||||
</form>
|
||||
`, ["Просмотреть", "Отменить"], [
|
||||
() => {
|
||||
document.querySelector("#back-codes-view-form").submit();
|
||||
}, Function.noop
|
||||
]);
|
||||
}
|
||||
|
||||
function disableTwoFactorAuth() {
|
||||
MessageBox("Отключить 2FA", `
|
||||
<form id="two-factor-auth-disable-form" method="post" action="/settings/2fa/disable">
|
||||
<label for="password">Пароль</label>
|
||||
<input type="password" id="password" name="password" required />
|
||||
<input type="hidden" name="hash" value={$csrfToken} />
|
||||
</form>
|
||||
`, ["Отключить", "Отменить"], [
|
||||
() => {
|
||||
document.querySelector("#two-factor-auth-disable-form").submit();
|
||||
}, Function.noop
|
||||
]);
|
||||
}
|
||||
</script>
|
||||
{else}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="accent-box">
|
||||
{_two_factor_authentication_disabled}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a class="button" href="/settings/2fa">{_connect}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<h4>{_your_email_address}</h4>
|
||||
function disableTwoFactorAuth() {
|
||||
MessageBox("Отключить 2FA", `
|
||||
<form id="two-factor-auth-disable-form" method="post" action="/settings/2fa/disable">
|
||||
<label for="password">Пароль</label>
|
||||
<input type="password" id="password" name="password" required />
|
||||
<input type="hidden" name="hash" value={$csrfToken} />
|
||||
</form>
|
||||
`, ["Отключить", "Отменить"], [
|
||||
() => {
|
||||
document.querySelector("#two-factor-auth-disable-form").submit();
|
||||
}, Function.noop
|
||||
]);
|
||||
}
|
||||
</script>
|
||||
{else}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="accent-box">
|
||||
{_two_factor_authentication_disabled}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a class="button" href="/settings/2fa">{_connect}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
<h4>{_ui_settings_sessions}</h4>
|
||||
<form action="/revokeAllTokens" method="POST">
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_current_email_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
{$user->getEmail()}
|
||||
<div class="accent-box">
|
||||
{tr("end_all_sessions_description", OPENVK_ROOT_CONF['openvk']['appearance']['name'])}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_new_email_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="email" name="new_email" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_password}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" name="email_change_pass" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr n:if="$user->is2faEnabled()">
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_"2fa_code"}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="email_change_code" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<input type="submit" value="{_save_email_address}" class="button" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<h4>{_your_page_address}</h4>
|
||||
<table cellspacing="7" cellpadding="0" width="60%" border="0" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_page_id}</span>
|
||||
</td>
|
||||
<td>
|
||||
{$user->getId()}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">{_page_address}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="sc" value="{$user->getShortCode()}" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<td width="120" valign="top" style="text-align: center;">
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" value="{_save}" class="button" />
|
||||
<input type="submit" value="{_end_all_sessions}" class="button" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<br/>
|
||||
<div class="settings_delete">
|
||||
{_you_can_also} <a onClick="showProfileDeactivateDialog({$csrfToken})">{_delete_your_page}</a>.
|
||||
</div>
|
||||
|
||||
|
||||
{elseif $isPrivacy}
|
||||
|
||||
<form action="/settings?act=privacy" method="POST" enctype="multipart/form-data">
|
||||
|
|
|
@ -543,12 +543,14 @@
|
|||
uBanMsgTxt = "Вы собираетесь забанить пользователя " + {$user->getCanonicalName()} + ".";
|
||||
uBanMsgTxt += "<br/><b>Предупреждение</b>: Это действие удалит все подписки пользователя и отпишет всех от него.";
|
||||
uBanMsgTxt += "<br/><br/><b>Причина бана</b>: <input type='text' id='uBanMsgInput' placeholder='придумайте что-нибудь крутое' />"
|
||||
|
||||
uBanMsgTxt += "<br/><br/><b>Заблокировать до</b>: <input type='date' id='uBanMsgDate' />";
|
||||
|
||||
MessageBox("Забанить " + {$user->getFirstName()}, uBanMsgTxt, ["Подтвердить", "Отмена"], [
|
||||
(function() {
|
||||
res = document.querySelector("#uBanMsgInput").value;
|
||||
date = document.querySelector("#uBanMsgDate").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/admin/ban/" + {$user->getId()} + "?reason=" + res + "&hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.open("GET", "/admin/ban/" + {$user->getId()} + "?reason=" + res + "&date=" + date + "&hash=" + {rawurlencode($csrfToken)}, true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("success") === -1)
|
||||
MessageBox("Ошибка", "Не удалось забанить пользователя...", ["OK"], [Function.noop]);
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<img src="/assets/packages/static/openvk/img/oof.apng" alt="Пользователь заблокирован." style="width: 20%;" />
|
||||
<p>
|
||||
{tr("user_banned", htmlentities($user->getFirstName()))|noescape}<br/>
|
||||
{_user_banned_comment} <b>{$user->getBanReason()}</b>.
|
||||
{_user_banned_comment} <b>{$user->getBanReason()}</b>.<br/>
|
||||
Пользователь заблокирован до: <b>{$user->getUnbanTime()}</b>
|
||||
</p>
|
||||
{if isset($thisUser)}
|
||||
<p n:if="$thisUser->getChandlerUser()->can('access')->model('admin')->whichBelongsTo(NULL) || $thisUser->getChandlerUser()->can('write')->model('openvk\Web\Models\Entities\TicketReply')->whichBelongsTo(0)">
|
||||
|
|
|
@ -2,5 +2,8 @@
|
|||
{var $user = $notification->getModel(1)}
|
||||
|
||||
<a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a>
|
||||
{$notification->getDateTime()} {_nt_liked_yours}
|
||||
{_nt_liked_yours}
|
||||
<a href="/wall{$post->getPrettyId()}"><b>{_nt_post_nominative}</b></a> {_nt_from} {$post->getPublicationTime()}.
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
||||
|
|
|
@ -2,5 +2,8 @@
|
|||
{var $user = $notification->getModel(1)}
|
||||
|
||||
<a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a>
|
||||
{$notification->getDateTime()} {_nt_shared_yours}
|
||||
{_nt_shared_yours}
|
||||
<a href="/wall{$post->getPrettyId()}"><b>{_nt_post_instrumental}</b></a> {_nt_from} {$post->getPublicationTime()}.
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
{var $user = $notification->getModel(1)}
|
||||
|
||||
<a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a>
|
||||
{$notification->getDateTime()} {_nt_commented_yours} {include under}: "{$notification->getData()}".
|
||||
{_nt_commented_yours} {include under}: "{$notification->getData()}".
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
|
@ -2,5 +2,8 @@
|
|||
{var $user = $notification->getModel(1)}
|
||||
|
||||
<a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a>
|
||||
{$notification->getDateTime()} {_nt_written_on_your_wall}
|
||||
{_nt_written_on_your_wall}
|
||||
<a href="/wall{$post->getPrettyId()}"><b>{_nt_post_nominative}</b></a>: "{$notification->getData()}".
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
|
@ -3,4 +3,7 @@
|
|||
|
||||
<a href="{$user->getURL()}"><b>{$user->getCanonicalName()}</b></a>
|
||||
{_nt_made_you_admin}
|
||||
<a href="{$club->getURL()}"><b>{$club->getCanonicalName()}</b></a> {$notification->getDateTime()}.
|
||||
<a href="{$club->getURL()}"><b>{$club->getCanonicalName()}</b></a>.
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
|
@ -1,4 +1,7 @@
|
|||
{var $gift = $notification->getModel(0)}
|
||||
{var $sender = $notification->getModel(1)}
|
||||
|
||||
<a href="{$sender->getURL()}"><b>{$sender->getCanonicalName()}</b></a> отправил вам {$notification->getDateTime()} подарок.
|
||||
<a href="{$sender->getURL()}"><b>{$sender->getCanonicalName()}</b></a> отправил вам подарок.
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
|
@ -6,3 +6,6 @@
|
|||
{if !empty($message)}
|
||||
{_message}: "{$message}".
|
||||
{/if}
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
|
@ -6,3 +6,6 @@
|
|||
{if !empty($message)}
|
||||
{_message}: "{$message}".
|
||||
{/if}
|
||||
<div class="nobold">
|
||||
{$notification->getDateTime()}
|
||||
</div>
|
|
@ -24,6 +24,7 @@ services:
|
|||
- openvk\Web\Presenters\AppsPresenter
|
||||
- openvk\Web\Presenters\ThemepacksPresenter
|
||||
- openvk\Web\Presenters\VKAPIPresenter
|
||||
- openvk\Web\Presenters\BannedLinkPresenter
|
||||
- openvk\Web\Models\Repositories\Users
|
||||
- openvk\Web\Models\Repositories\Posts
|
||||
- openvk\Web\Models\Repositories\Photos
|
||||
|
@ -47,3 +48,4 @@ services:
|
|||
- openvk\Web\Models\Repositories\Topics
|
||||
- openvk\Web\Models\Repositories\Applications
|
||||
- openvk\Web\Models\Repositories\ContentSearchRepository
|
||||
- openvk\Web\Models\Repositories\BannedLinks
|
||||
|
|
|
@ -93,6 +93,10 @@ routes:
|
|||
handler: "Auth->verifyEmail"
|
||||
- url: "/setSID/{slug}"
|
||||
handler: "Auth->su"
|
||||
- url: "/unban.php"
|
||||
handler: "Auth->unbanThemself"
|
||||
- url: "/revokeAllTokens"
|
||||
handler: "Auth->revokeAllTokens"
|
||||
- url: "/settings"
|
||||
handler: "User->settings"
|
||||
- url: "/settings/2fa"
|
||||
|
@ -281,6 +285,8 @@ routes:
|
|||
handler: "About->invite"
|
||||
- url: "/away.php"
|
||||
handler: "Away->away"
|
||||
- url: "/away.php/{num}"
|
||||
handler: "Away->view"
|
||||
- url: "/gift{num}_{num}.png"
|
||||
handler: "Gifts->giftImage"
|
||||
- url: "/gifts{num}"
|
||||
|
@ -327,6 +333,12 @@ routes:
|
|||
handler: "Support->quickBanInSupport"
|
||||
- url: "/admin/support/unban/{num}"
|
||||
handler: "Support->quickUnbanInSupport"
|
||||
- url: "/admin/bannedLinks"
|
||||
handler: "Admin->bannedLinks"
|
||||
- url: "/admin/bannedLink/id{num}"
|
||||
handler: "Admin->bannedLink"
|
||||
- url: "/admin/bannedLink/id{num}/unban"
|
||||
handler: "Admin->unbanLink"
|
||||
- url: "/upload/photo/{text}"
|
||||
handler: "VKAPI->photoUpload"
|
||||
- url: "/method/{text}.{text}"
|
||||
|
|
1
install/sqls/00031-ban-page-until.sql
Normal file
1
install/sqls/00031-ban-page-until.sql
Normal file
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `profiles` ADD `unblock_time` BIGINT UNSIGNED DEFAULT NULL AFTER `block_reason`;
|
14
install/sqls/00031-banned-urls.sql
Normal file
14
install/sqls/00031-banned-urls.sql
Normal file
|
@ -0,0 +1,14 @@
|
|||
CREATE TABLE `links_banned` (
|
||||
`id` bigint UNSIGNED NOT NULL,
|
||||
`domain` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
|
||||
`regexp_rule` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
|
||||
`reason` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
|
||||
`initiator` bigint UNSIGNED NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
ALTER TABLE `links_banned`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
ALTER TABLE `links_banned`
|
||||
MODIFY `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT;
|
||||
COMMIT;
|
|
@ -418,6 +418,7 @@
|
|||
"avatar" = "Avatar";
|
||||
"privacy" = "Privacy";
|
||||
"interface" = "Interface";
|
||||
"security" = "Security";
|
||||
|
||||
"profile_picture" = "Profile picture";
|
||||
|
||||
|
@ -490,6 +491,7 @@
|
|||
"ui_settings_view_of_posts_old" = "Old";
|
||||
"ui_settings_view_of_posts_microblog" = "Microblog";
|
||||
"ui_settings_main_page" = "Main page";
|
||||
"ui_settings_sessions" = "Sessions";
|
||||
|
||||
"additional_links" = "Additional links";
|
||||
"ad_poster" = "Ad poster";
|
||||
|
@ -518,6 +520,11 @@
|
|||
|
||||
"share_with_friends" = "Share with friends";
|
||||
|
||||
"end_all_sessions" = "End all sessions";
|
||||
"end_all_sessions_description" = "If you wanna logout from $1 on all devices, click on button below";
|
||||
|
||||
"end_all_sessions_done" = "All sessions was ended, including mobile apps";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Two-factor authentication";
|
||||
|
@ -835,8 +842,13 @@
|
|||
"banned_header" = "You are banned";
|
||||
"banned_alt" = "The user is blocked.";
|
||||
"banned_1" = "Sorry <b>$1</b>, but you have been banned.";
|
||||
"banned_2" = "And the reason for this is simple: <b>$1</b>. Unfortunately, this time we had to block you forever.";
|
||||
"banned_2" = "And the reason for this is simple: <b>$1</b>.";
|
||||
"banned_perm" = "Unfortunately, this time we had to block you forever.";
|
||||
"banned_until_time" = "This time we had to block you until <b>$1</b>";
|
||||
"banned_3" = "You can still <a href=\"/support?act=new\">write to the support</a> if you think there was an error or <a href=\"/logout?hash=$1\">logout</a>.";
|
||||
"banned_unban_myself" = "Unban myself";
|
||||
"banned_unban_title" = "Your account has been unbanned";
|
||||
"banned_unban_description" = "Try not to break the rules anymore.";
|
||||
|
||||
/* Registration confirm */
|
||||
|
||||
|
@ -1062,6 +1074,17 @@
|
|||
"admin_commerce_disabled" = "Commerce has been disabled by the system administrator";
|
||||
"admin_commerce_disabled_desc" = "The voucher and gift settings will be saved, but will have no effect.";
|
||||
|
||||
"admin_banned_links" = "Blocked links";
|
||||
"admin_banned_link" = "Link";
|
||||
"admin_banned_domain" = "Domain";
|
||||
"admin_banned_link_description" = "With the protocol (https://example.com/)";
|
||||
"admin_banned_link_regexp" = "Regular expression";
|
||||
"admin_banned_link_regexp_description" = "It is substituted after the domain specified above. Don't fill it out if you want to block the entire domain";
|
||||
"admin_banned_link_reason" = "Reason";
|
||||
"admin_banned_link_initiator" = "Initiator";
|
||||
"admin_banned_link_not_specified" = "The link is not specified";
|
||||
"admin_banned_link_not_found" = "Link not found";
|
||||
|
||||
/* Paginator (deprecated) */
|
||||
|
||||
"paginator_back" = "Back";
|
||||
|
@ -1160,4 +1183,14 @@
|
|||
"bug_tracker_success" = "Success";
|
||||
"bug_tracker_comment_sent" = "The comment has been sent.";
|
||||
"bug_tracker_fields_error" = "Not all fields are filled in.";
|
||||
"bug_tracker_reproduced_text" = "You have indicated that this bug is reproducible for you";
|
||||
"bug_tracker_reproduced_text" = "You have indicated that this bug is reproducible for you";
|
||||
|
||||
|
||||
/* Away */
|
||||
|
||||
"url_is_banned" = "Link is not allowed";
|
||||
"url_is_banned_comment" = "The <b>$1</b> administration recommends not to follow this link.";
|
||||
"url_is_banned_comment_r" = "The <b>$1</b> administration recommends not to follow this link.<br><br>The reason is: <b>$2</b>";
|
||||
"url_is_banned_default_reason" = "The link you are trying to open may lead you to a site that was created for the purpose of deceiving users with the intention of gaining profit.";
|
||||
"url_is_banned_title" = "Link to a suspicious site";
|
||||
"url_is_banned_proceed" = "Follow the link";
|
||||
|
|
|
@ -452,6 +452,7 @@
|
|||
"avatar" = "Аватар";
|
||||
"privacy" = "Приватность";
|
||||
"interface" = "Внешний вид";
|
||||
"security" = "Безопасность";
|
||||
|
||||
"profile_picture" = "Изображение страницы";
|
||||
|
||||
|
@ -526,6 +527,7 @@
|
|||
"ui_settings_view_of_posts_old" = "Старый";
|
||||
"ui_settings_view_of_posts_microblog" = "Микроблог";
|
||||
"ui_settings_main_page" = "Главная страница";
|
||||
"ui_settings_sessions" = "Сессии";
|
||||
|
||||
"additional_links" = "Дополнительные ссылки";
|
||||
"ad_poster" = "Рекламный плакат";
|
||||
|
@ -554,6 +556,11 @@
|
|||
|
||||
"share_with_friends" = "Рассказать друзьям";
|
||||
|
||||
"end_all_sessions" = "Сбросить все сессии";
|
||||
"end_all_sessions_description" = "Если вы хотите выйти из $1 со всех устройств, нажмите на кнопку ниже";
|
||||
|
||||
"end_all_sessions_done" = "Все сессии сброшены, включая мобильные приложения";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Двухфакторная аутентификация";
|
||||
|
@ -880,8 +887,13 @@
|
|||
"banned_header" = "Вы были верискокнуты";
|
||||
"banned_alt" = "Пользователь заблокирован.";
|
||||
"banned_1" = "Извините, <b>$1</b>, но вы были верискокнуты.";
|
||||
"banned_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось заблокировать вас навсегда.";
|
||||
"banned_2" = "А причина этому проста: <b>$1</b>.";
|
||||
"banned_perm" = "К сожалению, на этот раз нам пришлось заблокировать вас навсегда";
|
||||
"banned_until_time" = "На этот раз нам пришлось заблокировать вас до <b>$1</b>";
|
||||
"banned_3" = "Вы всё ещё можете <a href=\"/support?act=new\">написать в службу поддержки</a>, если считаете что произошла ошибка или <a href=\"/logout?hash=$1\">выйти</a>.";
|
||||
"banned_unban_myself" = "Разморозить страницу";
|
||||
"banned_unban_title" = "Ваш аккаунт разблокирован";
|
||||
"banned_unban_description" = "Постарайтесь больше не нарушать правила.";
|
||||
|
||||
/* Registration confirm */
|
||||
|
||||
|
@ -1111,6 +1123,17 @@
|
|||
"admin_commerce_disabled" = "Коммерция отключена системным администратором";
|
||||
"admin_commerce_disabled_desc" = "Настройки ваучеров и подарков будут сохранены, но не будут оказывать никакого влияния.";
|
||||
|
||||
"admin_banned_links" = "Заблокированные ссылки";
|
||||
"admin_banned_link" = "Ссылка";
|
||||
"admin_banned_domain" = "Домен";
|
||||
"admin_banned_link_description" = "С протоколом (https://example.com/)";
|
||||
"admin_banned_link_regexp" = "Регулярное выражение";
|
||||
"admin_banned_link_regexp_description" = "Подставляется после домена, указанного выше. Не заполняйте, если хотите заблокировать весь домен";
|
||||
"admin_banned_link_reason" = "Причина";
|
||||
"admin_banned_link_initiator" = "Инициатор";
|
||||
"admin_banned_link_not_specified" = "Ссылка не указана";
|
||||
"admin_banned_link_not_found" = "Ссылка не найдена";
|
||||
|
||||
/* Paginator (deprecated) */
|
||||
|
||||
"paginator_back" = "Назад";
|
||||
|
@ -1221,4 +1244,13 @@
|
|||
"bug_tracker_fields_error" = "Заполнены не все поля.";
|
||||
"bug_tracker_reproduced_text" = "Вы отметили, что у Вас получилось воспроизвести этот баг.";
|
||||
"bug_tracker_banned_1" = "Извините, <b>$1</b>, но Вы были исключены из программы <b>OVK Testers</b>.";
|
||||
"bug_tracker_banned_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось исключить Вас навсегда.";
|
||||
"bug_tracker_banned_2" = "А причина этому проста: <b>$1</b>. К сожалению, на этот раз нам пришлось исключить Вас навсегда.";
|
||||
|
||||
/* Away */
|
||||
|
||||
"url_is_banned" = "Переход невозможен";
|
||||
"url_is_banned_comment" = "Администрация <b>$1</b> не рекомендует переходить по этой ссылке.";
|
||||
"url_is_banned_comment_r" = "Администрация <b>$1</b> не рекомендует переходить по этой ссылке.<br><br>Причина: <b>$2</b>";
|
||||
"url_is_banned_default_reason" = "Ссылка, по которой вы попытались перейти, может вести на сайт, который был создан с целью обмана пользователей и получения за счёт этого прибыли.";
|
||||
"url_is_banned_title" = "Ссылка на подозрительный сайт";
|
||||
"url_is_banned_proceed" = "Перейти по ссылке";
|
||||
|
|
|
@ -11,17 +11,17 @@
|
|||
/* Login */
|
||||
|
||||
"log_in" = "Вход";
|
||||
"password" = "Пароль";
|
||||
"password" = "Проходное слово";
|
||||
"registration" = "Регистрация";
|
||||
"forgot_password" = "Забыли пароль?";
|
||||
"forgot_password" = "Забыли проходное слово?";
|
||||
|
||||
"login_failed" = "Не удалось войти";
|
||||
"invalid_username_or_password" = "Неверное имя пользователя или пароль. <a href='/restore.pl'>Забыли пароль?</a>";
|
||||
|
||||
"failed_to_register" = "Не удалось зарегистрироваться";
|
||||
"referral_link_invalid" = "Пригласительная ссылка недействительна.";
|
||||
"registration_disabled" = "Регистрация отключена системным администратором.";
|
||||
"user_already_exists" = "Пользователь с таким email уже существует.";
|
||||
"registration_disabled" = "Товарищ, регистрация отключена Имперской Канцелярией.";
|
||||
"user_already_exists" = "Гражданин с таким почтовым ящиком уже существует.";
|
||||
|
||||
"access_recovery" = "Восстановление доступа";
|
||||
"page_access_recovery" = "Восстановить доступ к странице";
|
||||
|
@ -30,25 +30,25 @@
|
|||
"reset_password" = "Сбросить пароль";
|
||||
"2fa_code_2" = "Код двухфакторной аутентификации";
|
||||
|
||||
"password_successfully_reset" = "Ваш пароль был успешно сброшен.";
|
||||
"password_reset_email_sent" = "Если вы зарегистрированы, вы получите инструкции на email.";
|
||||
"password_reset_error" = "Непредвиденная ошибка при сбросе пароля.";
|
||||
"password_successfully_reset" = "Ваше проходное слово было успешно сброшено.";
|
||||
"password_reset_email_sent" = "Если вы зарегистрированы, вы получите инструкции на почтовый ящик.";
|
||||
"password_reset_error" = "Непредвиденная ошибка при сбросе проходного слова.";
|
||||
"password_reset_rate_limit_error" = "Нельзя делать это так часто, извините.";
|
||||
|
||||
"registration_disabled_info" = "Регистрация отключена системным администратором. При возможности попросите приглашение у вашего знакомого, если он зарегистрирован на этом сайте.";
|
||||
"registration_disabled_info" = "Товарищ, регистрация отключена Имперской Канцелярией. При возможности попросите приглашение у вашего знакомого, если он зарегистрирован на этом сайте.";
|
||||
"registration_closed" = "Регистрация закрыта.";
|
||||
"invites_you_to" = "<strong>$1</strong> приглашает вас в $2";
|
||||
|
||||
"register_meta_desc" = "Зарегистрируйтесь в $1 прямо сейчас!";
|
||||
"register_referer_meta_title" = "$1 приглашает вас в $2!";
|
||||
"register_referer_meta_desc" = "Присоединяйтесь к $1 и множеству других пользователей в $2!";
|
||||
"register_referer_meta_desc" = "Присоединяйтесь к $1 и множеству других граждан в $2!";
|
||||
|
||||
"users" = "Пользователи";
|
||||
"users" = "Граждане";
|
||||
|
||||
/* Profile information */
|
||||
|
||||
"select_language" = "Выбрать язык";
|
||||
"edit" = "Изменить";
|
||||
"select_language" = "Выбрать менталитет";
|
||||
"edit" = "Корректировать";
|
||||
"birth_date" = "День рождения";
|
||||
"registration_date" = "Дата регистрации";
|
||||
"hometown" = "Родной город";
|
||||
|
@ -90,7 +90,7 @@
|
|||
"relationship_2" = "Встречаюсь";
|
||||
"relationship_3" = "Помолвлен";
|
||||
"relationship_4" = "Женат";
|
||||
"relationship_5" = "В гражданском браке";
|
||||
"relationship_5" = "Сожительствую";
|
||||
"relationship_6" = "Влюблен";
|
||||
"relationship_7" = "Всё сложно";
|
||||
"relationship_8" = "В активном поиске";
|
||||
|
@ -98,29 +98,29 @@
|
|||
"politViews" = "Полит. взгляды";
|
||||
|
||||
"politViews_0" = "Не выбраны";
|
||||
"politViews_1" = "Индифферентные";
|
||||
"politViews_1" = "Не в партии";
|
||||
"politViews_2" = "Коммунистические";
|
||||
"politViews_3" = "Социалистические";
|
||||
"politViews_4" = "Умеренные";
|
||||
"politViews_5" = "Либеральные";
|
||||
"politViews_4" = "Центристские";
|
||||
"politViews_5" = "Антисоветские";
|
||||
"politViews_6" = "Консервативные";
|
||||
"politViews_7" = "Монархические";
|
||||
"politViews_7" = "Контрреволюционные";
|
||||
"politViews_8" = "Ультраконсервативные";
|
||||
"politViews_9" = "Либертарианские";
|
||||
|
||||
"contact_information" = "Контактная информация";
|
||||
|
||||
"email" = "Почтовый ящик";
|
||||
"phone" = "Телефон";
|
||||
"phone" = "Стационарный телефон";
|
||||
"telegram" = "Telegram";
|
||||
"personal_website" = "Личная визитка";
|
||||
"city" = "Город";
|
||||
"address" = "Адрес";
|
||||
|
||||
"personal_information" = "Личная информация";
|
||||
"personal_information" = "Личность";
|
||||
|
||||
"interests" = "Интересы";
|
||||
"favorite_music" = "Любимые аудиозаписи";
|
||||
"favorite_music" = "Любимые звукозаписи";
|
||||
"favorite_films" = "Любимые киноленты";
|
||||
"favorite_shows" = "Любимые программы";
|
||||
"favorite_books" = "Любимые книги";
|
||||
|
@ -189,8 +189,8 @@
|
|||
"friends" = "Товарищи";
|
||||
"followers" = "Подписчики";
|
||||
"follower" = "Подписчик";
|
||||
"friends_add" = "Добавить в товарищи";
|
||||
"friends_delete" = "Удалить из товарищей";
|
||||
"friends_add" = "Взять в товарищи";
|
||||
"friends_delete" = "Отвергнуть товарища";
|
||||
"friends_reject" = "Порвать приглашение в товарищи";
|
||||
"friends_accept" = "Прочитать приглашение в товарищи";
|
||||
"send_message" = "Отправить телеграмму";
|
||||
|
@ -222,13 +222,13 @@
|
|||
"subscribe" = "Подписаться";
|
||||
"unsubscribe" = "Отписаться";
|
||||
"subscriptions" = "Подписки";
|
||||
"join_community" = "Вступить в группу";
|
||||
"leave_community" = "Выйти из группы";
|
||||
"join_community" = "Вступить в клуб";
|
||||
"leave_community" = "Выйти из клуба";
|
||||
"min_6_community" = "Название должно быть не менее 6 символов";
|
||||
"participants" = "Участники";
|
||||
"groups" = "Группы";
|
||||
"groups" = "Клубы";
|
||||
"meetings" = "Встречи";
|
||||
"create_group" = "Создать группу";
|
||||
"create_group" = "Создать клуб";
|
||||
"group_managers" = "Руководство";
|
||||
"group_type" = "Тип группы";
|
||||
"group_type_open" = "Это открытая группа. В неё может вступить любой желающий.";
|
||||
|
@ -263,7 +263,7 @@
|
|||
"group_dont_display_administrators_list" = "Ничего не отображать";
|
||||
|
||||
"group_changeowner_modal_title" = "Передача прав владельца";
|
||||
"group_changeowner_modal_text" = "Внимание! Вы передаёте права владельца пользователю $1. Это действие необратимо. После передави вы останетесь адмиинстратором, но сможете легко перестать им быть.";
|
||||
"group_changeowner_modal_text" = "Внимание! Вы передаёте права владельца пользователю $1. Это действие необратимо. После передачи вы останетесь адмиинстратором, но сможете легко перестать им быть.";
|
||||
"group_owner_setted" = "Новый владелец ($1) успешно назначен в сообщество $2. Вам выданы права администратора в сообществе. Если Вы хотите вернуть роль владельца, обратитесь в <a href='/support?act=new'>техническую поддержку сайта</a>.";
|
||||
|
||||
"participants_zero" = "Ни одного участника";
|
||||
|
@ -340,8 +340,8 @@
|
|||
"menu_registration" = "Регистрация";
|
||||
"menu_help" = "Справка";
|
||||
|
||||
"menu_logout" = "Выйти";
|
||||
"menu_support" = "Поддержка";
|
||||
"menu_logout" = "Эмигрировать";
|
||||
"menu_support" = "Справочная";
|
||||
|
||||
"header_home" = "главная";
|
||||
"header_groups" = "клубы";
|
||||
|
@ -646,12 +646,12 @@
|
|||
"support_new_title" = "Введите тему вашего обращения";
|
||||
"support_new_content" = "Опишите проблему или предложение";
|
||||
|
||||
"support_rate_good_answer" = "Это хороший ответ";
|
||||
"support_rate_bad_answer" = "Это плохой ответ";
|
||||
"support_good_answer_user" = "Вы оставили положительный отзыв.";
|
||||
"support_bad_answer_user" = "Вы оставили негативный отзыв.";
|
||||
"support_good_answer_agent" = "Гражданин оставил положительный отзыв";
|
||||
"support_bad_answer_agent" = "Гражданин оставил негативный отзыв";
|
||||
"support_rate_good_answer" = "Подарить конфеты";
|
||||
"support_rate_bad_answer" = "Закатить скандал";
|
||||
"support_good_answer_user" = "Вы подарили конфеты сотруднику справочной.";
|
||||
"support_bad_answer_user" = "Вы закатили скандал сотруднику справочной.";
|
||||
"support_good_answer_agent" = "Гражданин подарил конфеты сотруднику справочной";
|
||||
"support_bad_answer_agent" = "Гражданин закатил скандал сотруднику справочной";
|
||||
"support_rated_good" = "Вы оставили положительный отзыв об ответе.";
|
||||
"support_rated_bad" = "Вы оставили негативный отзыв об ответе.";
|
||||
"wrong_parameters" = "Неверные параметры запроса.";
|
||||
|
@ -683,7 +683,7 @@
|
|||
"banned_alt" = "Гражданин был отправлен в тюрьму.";
|
||||
"banned_1" = "Извините, <b>$1</b>, но вы были отправлены в тюрьму.";
|
||||
"banned_2" = "А причина этому проста: <b>$1</b>. Органу в этот раз пришлось отправить вас под стражу навсегда.";
|
||||
"banned_3" = "Вы всё ещё можете <a href=\"/support?act=new\">написать в службу поддержки</a>, если считаете что произошла ошибка или <a href=\"/logout?hash=$1\">выйти</a>.";
|
||||
"banned_3" = "Вы всё ещё можете <a href=\"/support?act=new\">написать в Справочную</a>, если считаете что произошла ошибка или <a href=\"/logout?hash=$1\">эмигрировать</a>.";
|
||||
|
||||
/* Discussions */
|
||||
|
||||
|
@ -822,15 +822,15 @@
|
|||
"about_users_many" = "<b>$1</b> гражданинов";
|
||||
"about_users_other" = "<b>$1</b> гражданинов";
|
||||
|
||||
"about_online_users_one" = "<b>1</b> пользователь в сети";
|
||||
"about_online_users_few" = "<b>$1</b> пользователя в сети";
|
||||
"about_online_users_many" = "<b>$1</b> гражданинов в сети";
|
||||
"about_online_users_other" = "<b>$1</b> гражданинов в сети";
|
||||
"about_online_users_one" = "<b>1</b> гражданин в сети";
|
||||
"about_online_users_few" = "<b>$1</b> гражданина в сети";
|
||||
"about_online_users_many" = "<b>$1</b> граждан в сети";
|
||||
"about_online_users_other" = "<b>$1</b> граждан в сети";
|
||||
|
||||
"about_active_users_one" = "<b>1</b> активный пользователь";
|
||||
"about_active_users_few" = "<b>$1</b> активных пользователя";
|
||||
"about_active_users_many" = "<b>$1</b> активных гражданинов";
|
||||
"about_active_users_other" = "<b>$1</b> активных гражданинов";
|
||||
"about_active_users_one" = "<b>1</b> активный гражданин";
|
||||
"about_active_users_few" = "<b>$1</b> активных граждан";
|
||||
"about_active_users_many" = "<b>$1</b> активных граждан";
|
||||
"about_active_users_other" = "<b>$1</b> активных граждан";
|
||||
|
||||
"about_groups_one" = "<b>1</b> клуб";
|
||||
"about_groups_few" = "<b>$1</b> клубы";
|
||||
|
@ -860,7 +860,6 @@
|
|||
|
||||
"user_alert_scam" = "Органу управления было дозволено, что данный гражданин обманывает товарищей на денежные средства. Будьте осторожны при разговоре с ним.";
|
||||
|
||||
|
||||
"ec_header" = "Подтверждение регистрации прописки";
|
||||
"ec_title" = "Спасибо!";
|
||||
"ec_1" = "<b>$1</b>, на ваш почтовый ящик должно придти письмо с подтверждением регистрации.";
|
||||
|
@ -872,4 +871,17 @@
|
|||
"email_error" = "Непредвиденная ошибка при отправке письма.";
|
||||
"email_rate_limit_error" = "Нельзя делать это так часто, извините.";
|
||||
|
||||
"email_verify_success" = "Ваша регистрация была подтверждена. Приятного времяпрепровождения!";
|
||||
"email_verify_success" = "Ваша регистрация была подтверждена. Приятного времяпрепровождения!";
|
||||
|
||||
"you_still_have_x_points" = "У Вас <b>$1</b> неиспользованных совестких рублей.";
|
||||
"top_up_your_account" = "Пополнить баланс";
|
||||
|
||||
"transfer_trough_ton" = "Пополнить с помощью ТОН";
|
||||
"transfer_ton_contents" = "Вы можете пополнить ваш баланс с помощью криптовалюты ТОН. Достаточно отсканировать КуАр-код приложением Tonkeeper, или вручную отправить ТОН по реквизитам. В течении нескольких минут вам придут определенное количество рублей.";
|
||||
"transfer_ton_address" = "<b>Адрес кошелька:</b> $1<br/><b>Содержание телеграммы:</b> $2";
|
||||
"transfer_ton_currency_per_ton" = "$1 TON";
|
||||
|
||||
"about_links" = "Ссылки";
|
||||
"instance_links" = "Ссылки страны:";
|
||||
|
||||
"my_apps" = "Досуг и отдых";
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "uk_UA.utf8;Ukr";
|
||||
"__WinEncoding" = "Windows-1251";
|
||||
|
||||
|
@ -453,6 +451,7 @@
|
|||
"avatar" = "Аватар";
|
||||
"privacy" = "Приватність";
|
||||
"interface" = "Зовнішній вид";
|
||||
"security" = "Безпека";
|
||||
|
||||
"profile_picture" = "Зображення сторінки";
|
||||
|
||||
|
@ -527,6 +526,7 @@
|
|||
"ui_settings_view_of_posts_old" = "Старий";
|
||||
"ui_settings_view_of_posts_microblog" = "Мікроблог";
|
||||
"ui_settings_main_page" = "Головна сторінка";
|
||||
"ui_settings_sessions" = "Сеанси";
|
||||
|
||||
"additional_links" = "Додаткові посилання";
|
||||
"ad_poster" = "Рекламний плакат";
|
||||
|
@ -555,6 +555,11 @@
|
|||
|
||||
"share_with_friends" = "Розповісти друзям";
|
||||
|
||||
"end_all_sessions" = "Завершити всі сеанси";
|
||||
"end_all_sessions_description" = "Якщо ви хочете вийти з $1 на всіх пристроях, натисніть кнопку нижче";
|
||||
|
||||
"end_all_sessions_done" = "<b>Усі</b> сеанси було завершено";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Двофакторна автентифікація";
|
||||
|
@ -827,12 +832,12 @@
|
|||
|
||||
"support_opened" = "Відкриті";
|
||||
"support_answered" = "З відповіддю";
|
||||
"support_closed" = "Закриті";
|
||||
"support_closed" = "Зачинені";
|
||||
"support_ticket" = "Звернення";
|
||||
"support_tickets" = "Звернення";
|
||||
"support_status_0" = "Питання на розгляді";
|
||||
"support_status_1" = "Є відповідь";
|
||||
"support_status_2" = "Закрито";
|
||||
"support_status_2" = "Зачинено";
|
||||
"support_greeting_hi" = "Вітаємо, $1!";
|
||||
"support_greeting_regards" = "З повагою,<br/>команда підтримки $1.";
|
||||
|
||||
|
@ -880,9 +885,14 @@
|
|||
"banned_title" = "Обліковий запис заблоковано";
|
||||
"banned_header" = "Ваш обліковий запис заблоковано.";
|
||||
"banned_alt" = "Користувача заблоковано.";
|
||||
"banned_1" = "<b>$1</b>, ваш акаунт заблоковано за порушення правил користування сайту.";
|
||||
"banned_2" = "Підстава: <b>$1</b>. На цей раз, нам довелося заблокувати вас назавжди.";
|
||||
"banned_1" = "<b>$1</b>, ваш обліковий запис заблоковано за порушення правил користування сайту.";
|
||||
"banned_2" = "Привід: <b>$1</b>.";
|
||||
"banned_perm" = "На цей раз, Ви заблоковані назавжди.";
|
||||
"banned_until_time" = "На цей раз, Ви заблоковані до <b>$1</b>";
|
||||
"banned_3" = "Ви все ще можете <a href=\"/support?act=new\">написати в службу підтримки</a>, якщо вважаєте, що сталася помилка або <a href=\"/logout?hash= $1\">вийти</a>.";
|
||||
"banned_unban_myself" = "Розблокувати сторінку";
|
||||
"banned_unban_title" = "Ваш обліковий запис розблокований";
|
||||
"banned_unban_description" = "Намагайтеся, більше не порушувати правила.";
|
||||
|
||||
/* Registration confirm */
|
||||
|
||||
|
|
|
@ -55,6 +55,9 @@ openvk:
|
|||
processingLimit: 3000
|
||||
emojiProcessingLimit: 1000
|
||||
commerce: false
|
||||
susLinks:
|
||||
warnings: true
|
||||
showReason: true
|
||||
ton:
|
||||
enabled: false
|
||||
address: "🅿"
|
||||
|
|
|
@ -223,7 +223,7 @@ input[type=checkbox] {
|
|||
}
|
||||
|
||||
.ovk-diag-action {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
|
@ -231,20 +231,6 @@ input[type=checkbox] {
|
|||
border-bottom: none;
|
||||
}
|
||||
|
||||
.floating_sidebar {
|
||||
position: fixed;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
align-items: start;
|
||||
width: 21%;
|
||||
}
|
||||
.minilink .counter {
|
||||
background-color: #2B587A;
|
||||
margin: 0;
|
||||
padding: 0.5px 2px;
|
||||
left: 10px;
|
||||
font-size: 7px;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
margin-top: -6px;
|
||||
.floating_sidebar,.floating_sidebar.show {
|
||||
display:none
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue