mirror of
https://github.com/openvk/openvk
synced 2025-07-08 16:53:02 +03:00
Merge branch 'openvk:master' into master
This commit is contained in:
commit
8ea6204e4d
46 changed files with 540 additions and 231 deletions
0
.gitmodules
vendored
0
.gitmodules
vendored
|
@ -10,7 +10,7 @@ To be honest, we don't even know whether it even works. However, this version is
|
|||
|
||||
Please use the master branch, as it has the most changes.
|
||||
|
||||
Updating the source code is done with this command: `git pull --recurse-submodules`
|
||||
Updating the source code is done with this command: `git pull`
|
||||
|
||||
## Instances
|
||||
|
||||
|
@ -29,7 +29,7 @@ If you want, you can add your instance to the list above so that people can regi
|
|||
* PHP 8 has **not** yet been tested, so you should not expect it to work.
|
||||
2. Install [commitcaptcha](https://github.com/openvk/commitcaptcha) and OpenVK as Chandler extensions like this:
|
||||
```
|
||||
git clone --recursive https://github.com/openvk/openvk /path/to/chandler/extensions/available/openvk
|
||||
git clone https://github.com/openvk/openvk /path/to/chandler/extensions/available/openvk
|
||||
git clone https://github.com/openvk/commitcaptcha /path/to/chandler/extensions/available/commitcaptcha
|
||||
```
|
||||
3. And enable them:
|
||||
|
@ -44,8 +44,6 @@ ln -s /path/to/chandler/extensions/available/openvk /path/to/chandler/extensions
|
|||
8. Move to `Web/static/js` and execute `yarn install`
|
||||
9. Set `openvk` as your root app in `chandler.yml`
|
||||
|
||||
**Note**: If OVK submodules were not downloaded beforehand (i.e. `--recursive` was not used during cloning), this command *must be* executed in the `openvk` folder: `git submodule update --init`
|
||||
|
||||
Once you are done, you can login as a system administrator on the network itself (no registration required):
|
||||
* **Login**: `admin@localhost.localdomain6`
|
||||
* **Password**: `admin`
|
||||
|
|
|
@ -135,6 +135,11 @@ class Club extends RowModel
|
|||
return (bool) $this->getRecord()->everyone_can_create_topics;
|
||||
}
|
||||
|
||||
function isDisplayTopicsAboveWallEnabled(): bool
|
||||
{
|
||||
return (bool) $this->getRecord()->display_topics_above_wall;
|
||||
}
|
||||
|
||||
function getType(): int
|
||||
{
|
||||
return $this->getRecord()->type;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Entities\Notifications;
|
||||
use openvk\Web\Models\Entities\{User, Gift};
|
||||
|
||||
final class CoinsTransferNotification extends Notification
|
||||
{
|
||||
protected $actionCode = 9602;
|
||||
|
||||
function __construct(User $receiver, User $sender, int $value, string $message)
|
||||
{
|
||||
parent::__construct($receiver, $receiver, $sender, time(), $value . " " . $message);
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@ trait TRichText
|
|||
$rel = $this->isAd() ? "sponsored" : "ugc";
|
||||
$text = $this->formatLinks($text);
|
||||
$text = preg_replace("%@([A-Za-z0-9]++) \(([\p{L} 0-9]+)\)%Xu", "[$1|$2]", $text);
|
||||
$text = preg_replace("%@([A-Za-z0-9]++)%Xu", "[$1|@$1]", $text);
|
||||
$text = preg_replace("%([\n\r\s]|^)(@([A-Za-z0-9]++))%Xu", "$1[$3|@$3]", $text);
|
||||
$text = preg_replace("%\[([A-Za-z0-9]++)\|([\p{L} 0-9@]+)\]%Xu", "<a href='/$1'>$2</a>", $text);
|
||||
$text = preg_replace("%(#([\p{L}_-]++[0-9]*[\p{L}_-]*))%Xu", "<a href='/feed/hashtag/$2'>$1</a>", $text);
|
||||
$text = $this->formatEmojis($text);
|
||||
|
|
|
@ -52,6 +52,23 @@ class Users
|
|||
"online" => sizeof((clone $this->users)->where("online >= ?", time() - 900)),
|
||||
];
|
||||
}
|
||||
|
||||
function getByAddress(string $address): ?User
|
||||
{
|
||||
if(substr_compare($address, "/", -1) === 0)
|
||||
$address = substr($address, 0, iconv_strlen($address) - 1);
|
||||
|
||||
$serverUrl = ovk_scheme(true) . $_SERVER["SERVER_NAME"];
|
||||
if(strpos($address, $serverUrl . "/") === 0)
|
||||
$address = substr($address, iconv_strlen($serverUrl) + 1);
|
||||
|
||||
if(strpos($address, "id") === 0) {
|
||||
$user = $this->get((int) substr($address, 2));
|
||||
if($user) return $user;
|
||||
}
|
||||
|
||||
return $this->getByShortUrl($address);
|
||||
}
|
||||
|
||||
use \Nette\SmartObject;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ final class GroupPresenter extends OpenVKPresenter
|
|||
$club->setWall(empty($this->postParam("wall")) ? 0 : 1);
|
||||
$club->setAdministrators_List_Display(empty($this->postParam("administrators_list_display")) ? 0 : $this->postParam("administrators_list_display"));
|
||||
$club->setEveryone_Can_Create_Topics(empty($this->postParam("everyone_can_create_topics")) ? 0 : 1);
|
||||
$club->setDisplay_Topics_Above_Wall(empty($this->postParam("display_topics_above_wall")) ? 0 : 1);;
|
||||
|
||||
$website = $this->postParam("website") ?? "";
|
||||
if(empty($website))
|
||||
|
|
|
@ -138,12 +138,13 @@ final class PhotosPresenter extends OpenVKPresenter
|
|||
}
|
||||
|
||||
$this->template->album = $album;
|
||||
$this->template->photos = iterator_to_array( $album->getPhotos( (int) ($this->queryParam("p") ?? 1) ) );
|
||||
$this->template->photos = iterator_to_array( $album->getPhotos( (int) ($this->queryParam("p") ?? 1), 20) );
|
||||
$this->template->paginatorConf = (object) [
|
||||
"count" => $album->getPhotosCount(),
|
||||
"page" => $this->queryParam("p") ?? 1,
|
||||
"amount" => sizeof($this->template->photos),
|
||||
"perPage" => OPENVK_DEFAULT_PER_PAGE,
|
||||
"perPage" => 20,
|
||||
"atBottom" => true
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use openvk\Web\Models\Repositories\Videos;
|
|||
use openvk\Web\Models\Repositories\Notes;
|
||||
use openvk\Web\Models\Repositories\Vouchers;
|
||||
use openvk\Web\Util\Validator;
|
||||
use openvk\Web\Models\Entities\Notifications\CoinsTransferNotification;
|
||||
use Chandler\Security\Authenticator;
|
||||
use lfkeitel\phptotp\{Base32, Totp};
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
@ -465,4 +466,42 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$this->user->identity->save();
|
||||
$this->flashFail("succ", tr("information_-1"), tr("two_factor_authentication_disabled_message"));
|
||||
}
|
||||
|
||||
function renderCoinsTransfer(): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
$receiverAddress = $this->postParam("receiver");
|
||||
$value = (int) $this->postParam("value");
|
||||
$message = $this->postParam("message");
|
||||
|
||||
if(!$receiverAddress || !$value)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("not_all_information_has_been_entered"));
|
||||
|
||||
if($value < 0)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("negative_transfer_value"));
|
||||
|
||||
if(iconv_strlen($message) > 255)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("message_is_too_long"));
|
||||
|
||||
$receiver = $this->users->getByAddress($receiverAddress);
|
||||
if(!$receiver)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("receiver_not_found"));
|
||||
|
||||
if($this->user->identity->getCoins() < $value)
|
||||
$this->flashFail("err", tr("failed_to_tranfer_points"), tr("you_dont_have_enough_points"));
|
||||
|
||||
if($this->user->id !== $receiver->getId()) {
|
||||
$this->user->identity->setCoins($this->user->identity->getCoins() - $value);
|
||||
$this->user->identity->save();
|
||||
|
||||
$receiver->setCoins($receiver->getCoins() + $value);
|
||||
$receiver->save();
|
||||
|
||||
(new CoinsTransferNotification($receiver, $this->user->identity, $value, $message))->emit();
|
||||
}
|
||||
|
||||
$this->flashFail("succ", tr("information_-1"), tr("points_transfer_successful", tr("points_amount", $value), $receiver->getURL(), htmlentities($receiver->getCanonicalName())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
{include description, x => $dat}
|
||||
</td>
|
||||
<td n:ifset="actions" valign="top" class="action_links" style="width: 150px">
|
||||
{include actions, x => $dat}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{extends "../@layout.xml"}
|
||||
|
||||
{block title}Об OpenVK{/block}
|
||||
{block title}{_about_openvk}{/block}
|
||||
|
||||
{block header}
|
||||
Об OpenVK
|
||||
{_about_openvk}
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
|
@ -343,7 +343,7 @@
|
|||
<tbody>
|
||||
<tr class="h">
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th style="width: 50px;">Status</th>
|
||||
<th>Version</th>
|
||||
<th>Description</th>
|
||||
<th>Author</th>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{/block}
|
||||
|
||||
{block description}
|
||||
<table class="ugc-table" n:if="$hideInfo ? !$x->anon : true">
|
||||
<table class="ugc-table" n:if="$hideInfo ? (!$x->anon || $x->sender->getId() === $thisUser->getId()) : true">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="nobold">{_sender}: </span></td>
|
||||
|
|
|
@ -82,7 +82,8 @@
|
|||
<span class="nobold">{_discussions}: </span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="everyone_can_create_topics" value="1" n:attr="checked => $club->isEveryoneCanCreateTopics()" /> {_everyone_can_create_topics}
|
||||
<input type="checkbox" name="everyone_can_create_topics" value="1" n:attr="checked => $club->isEveryoneCanCreateTopics()" /> {_everyone_can_create_topics}<br>
|
||||
<input type="checkbox" name="display_topics_above_wall" value="1" n:attr="checked => $club->isDisplayTopicsAboveWallEnabled()" /> {_display_list_of_topics_above_wall}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
<a n:if="$onlyShowManagers" href="/club{$club->getId()}/followers" style="float: right;">{_only_administrators}</a>
|
||||
{/block}
|
||||
|
||||
{block actions}
|
||||
|
||||
{/block}
|
||||
|
||||
{* BEGIN ELEMENTS DESCRIPTION *}
|
||||
|
||||
{block tabs}
|
||||
|
@ -81,50 +77,13 @@
|
|||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
<tr n:if="$club->canBeModifiedBy($thisUser ?? NULL)">
|
||||
<td width="120" valign="top"><span class="nobold">{_actions}: </span></td>
|
||||
<td>
|
||||
<a href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hash={rawurlencode($csrfToken)}" n:if="$club->getOwner()->getId() !== $user->getId()">
|
||||
{if $manager}
|
||||
{_devote}
|
||||
{else}
|
||||
{_promote_to_admin}
|
||||
{/if}
|
||||
</a>
|
||||
{if $club->getOwner()->getId() != $user->getId() && $manager && $thisUser->getId() == $club->getOwner()->getId()}
|
||||
|
|
||||
<a href="javascript:changeOwner({$club->getId()}, {$user->getId()})">
|
||||
{_promote_to_owner}
|
||||
</a>
|
||||
{/if}
|
||||
{if $manager}
|
||||
|
|
||||
<a href="javascript:setClubAdminComment('{$club->getId()}', '{$manager->getUserId()}', '{rawurlencode($csrfToken)}')">
|
||||
{_set_comment}
|
||||
</a>
|
||||
{/if}
|
||||
<a n:if="$club->getOwner()->getId() === $user->getId()" href="javascript:setClubAdminComment('{$club->getId()}', '{$club->getOwner()->getId()}', '{rawurlencode($csrfToken)}')">
|
||||
{_set_comment}
|
||||
</a>
|
||||
{if $manager}
|
||||
|
|
||||
<a href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hidden={(int) !$manager->isHidden()}&hash={rawurlencode($csrfToken)}">
|
||||
{if $manager->isHidden()}{_hidden_yes}{else}{_hidden_no}{/if}
|
||||
</a>
|
||||
{/if}
|
||||
{if $club->getOwner()->getId() == $user->getId()}
|
||||
|
|
||||
<a href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hidden={(int) !$club->isOwnerHidden()}&hash={rawurlencode($csrfToken)}">
|
||||
{if $club->isOwnerHidden()}{_hidden_yes}{else}{_hidden_no}{/if}
|
||||
</a>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script n:if="$club->getOwner()->getId() != $user->getId() && $manager && $thisUser->getId() == $club->getOwner()->getId()">
|
||||
console.log("gayshit")
|
||||
console.log("gayshit");
|
||||
console.log("сам такой");
|
||||
function changeOwner(club, newOwner) {
|
||||
const action = "/groups/" + club + "/setNewOwner/" + newOwner;
|
||||
|
||||
|
@ -145,3 +104,40 @@
|
|||
}
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
{block actions}
|
||||
{var user = $x instanceof $Manager ? $x->getUser() : $x}
|
||||
{var manager = $x instanceof $Manager ? $x : $club->getManager($user, !$club->canBeModifiedBy($thisUser))}
|
||||
{if $club->canBeModifiedBy($thisUser ?? NULL)}
|
||||
<a class="profile_link" href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hash={rawurlencode($csrfToken)}" n:if="$club->getOwner()->getId() !== $user->getId()">
|
||||
{if $manager}
|
||||
{_devote}
|
||||
{else}
|
||||
{_promote_to_admin}
|
||||
{/if}
|
||||
</a>
|
||||
{if $club->getOwner()->getId() != $user->getId() && $manager && $thisUser->getId() == $club->getOwner()->getId()}
|
||||
<a class="profile_link" href="javascript:changeOwner({$club->getId()}, {$user->getId()})">
|
||||
{_promote_to_owner}
|
||||
</a>
|
||||
{/if}
|
||||
{if $manager}
|
||||
<a class="profile_link" href="javascript:setClubAdminComment('{$club->getId()}', '{$manager->getUserId()}', '{rawurlencode($csrfToken)}')">
|
||||
{_set_comment}
|
||||
</a>
|
||||
{/if}
|
||||
<a class="profile_link" n:if="$club->getOwner()->getId() === $user->getId()" href="javascript:setClubAdminComment('{$club->getId()}', '{$club->getOwner()->getId()}', '{rawurlencode($csrfToken)}')">
|
||||
{_set_comment}
|
||||
</a>
|
||||
{if $manager}
|
||||
<a class="profile_link" href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hidden={(int) !$manager->isHidden()}&hash={rawurlencode($csrfToken)}">
|
||||
{if $manager->isHidden()}{_hidden_yes}{else}{_hidden_no}{/if}
|
||||
</a>
|
||||
{/if}
|
||||
{if $club->getOwner()->getId() == $user->getId()}
|
||||
<a class="profile_link" href="/club{$club->getId()}/setAdmin.jsp?user={$user->getId()}&hidden={(int) !$club->isOwnerHidden()}&hash={rawurlencode($csrfToken)}">
|
||||
{if $club->isOwnerHidden()}{_hidden_yes}{else}{_hidden_no}{/if}
|
||||
</a>
|
||||
{/if}
|
||||
{/if}
|
||||
{/block}
|
|
@ -41,45 +41,54 @@
|
|||
</table>
|
||||
</div>
|
||||
<div n:if="$club->getFollowersCount() > 0">
|
||||
{var followersCount = $club->getFollowersCount()}
|
||||
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$followersCount});">
|
||||
{_participants}
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_subtitle">
|
||||
{tr("participants", $followersCount)}
|
||||
<div style="float:right;">
|
||||
<a href="/club{$club->getId()}/followers">{_all_title}</a>
|
||||
</div>
|
||||
{var followersCount = $club->getFollowersCount()}
|
||||
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$followersCount});">
|
||||
{_participants}
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_subtitle">
|
||||
{tr("participants", $followersCount)}
|
||||
<div style="float:right;">
|
||||
<a href="/club{$club->getId()}/followers">{_all_title}</a>
|
||||
</div>
|
||||
<div style="padding-left: 5px;">
|
||||
<table
|
||||
n:foreach="$club->getFollowers(1) as $follower"
|
||||
n:class="User"
|
||||
style="text-align:center;display:inline-block;width:62px"
|
||||
cellspacing=4>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{$follower->getURL()}">
|
||||
<img src="{$follower->getAvatarUrl()}" width="50" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{$follower->getURL()}">{$follower->getFirstName()}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="padding-left: 5px;" class="content_list long">
|
||||
<div class="cl_element" n:foreach="$club->getFollowers(1) as $follower">
|
||||
<div class="cl_avatar">
|
||||
<a href="{$follower->getURL()}">
|
||||
<img class="ava" src="{$follower->getAvatarUrl()}" />
|
||||
</a>
|
||||
</div>
|
||||
<a href="{$follower->getURL()}" class="cl_name">
|
||||
<text class="cl_fname">{$follower->getFirstName()}</text>
|
||||
<text class="cl_lname">{$follower->getLastName()}</text>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div n:if="($topicsCount > 0 || $club->isEveryoneCanCreateTopics() || ($thisUser && $club->canBeModifiedBy($thisUser))) && $club->isDisplayTopicsAboveWallEnabled()">
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$topicsCount});">
|
||||
{_discussions}
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_subtitle">
|
||||
{tr("topics", $topicsCount)}
|
||||
<div style="float: right;">
|
||||
<a href="/board{$club->getId()}">{_"all_title"}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div n:foreach="$topics as $topic" class="topic-list-item" style="padding: 8px;">
|
||||
<b><a href="/topic{$topic->getPrettyId()}">{$topic->getTitle()}</a></b><br>
|
||||
<span class="nobold">{tr("updated_at", $topic->getUpdateTime())}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{presenter "openvk!Wall->wallEmbedded", -$club->getId()}
|
||||
|
||||
</div>
|
||||
<div class="right_small_block">
|
||||
<a href="{$club->getAvatarLink()|nocheck}">
|
||||
|
@ -203,7 +212,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div n:if="$topicsCount > 0 || $club->isEveryoneCanCreateTopics() || $club->canBeModifiedBy($thisUser)">
|
||||
<div n:if="($topicsCount > 0 || $club->isEveryoneCanCreateTopics() || ($thisUser && $club->canBeModifiedBy($thisUser))) && !$club->isDisplayTopicsAboveWallEnabled()">
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$topicsCount});">
|
||||
{_discussions}
|
||||
</div>
|
||||
|
|
|
@ -19,13 +19,6 @@
|
|||
</div>
|
||||
{/block}
|
||||
|
||||
{block actions}
|
||||
<div class="tile">
|
||||
<a class="profile_link" href="?">{_unreaded}</a>
|
||||
<a class="profile_link" href="?act=archived">{_archive}</a>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{* BEGIN ELEMENTS DESCRIPTION *}
|
||||
|
||||
{block link|strip|stripHtml}
|
||||
|
|
|
@ -27,23 +27,24 @@
|
|||
|
|
||||
<a href="/album{$album->getPrettyId()}/edit">{_"edit_album"}</a>
|
||||
{/if}
|
||||
<br/>
|
||||
<br/><br/>
|
||||
{if $album->getPhotosCount() > 0}
|
||||
{foreach $photos as $photo}
|
||||
{php if($photo->isDeleted()) continue; }
|
||||
<div class="album-photo" style="display: inline-table;">
|
||||
<a
|
||||
n:if="!is_null($thisUser) && $album->canBeModifiedBy($thisUser)"
|
||||
href="/album{$album->getPrettyId()}/remove_photo.pl/{$photo->getId()}" class="album-photo--delete">
|
||||
×
|
||||
</a>
|
||||
|
||||
<a href="/photo{$photo->getPrettyId()}?from=album{$album->getId()}">
|
||||
<img class="album-photo--image" src="{$photo->getURL()}" alt="{$photo->getDescription()}" style="width:unset;max-height:unset;max-width: 188px;" />
|
||||
</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
||||
<div class="container_gray album-flex">
|
||||
{foreach $photos as $photo}
|
||||
{php if($photo->isDeleted()) continue; }
|
||||
<div class="album-photo">
|
||||
<a
|
||||
n:if="!is_null($thisUser) && $album->canBeModifiedBy($thisUser)"
|
||||
href="/album{$album->getPrettyId()}/remove_photo.pl/{$photo->getId()}" class="album-photo--delete">
|
||||
×
|
||||
</a>
|
||||
|
||||
<a href="/photo{$photo->getPrettyId()}?from=album{$album->getId()}">
|
||||
<img class="album-photo--image" src="{$photo->getURL()}" alt="{$photo->getDescription()}" />
|
||||
</a>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{include "../components/paginator.xml", conf => $paginatorConf}
|
||||
{else}
|
||||
{include "../components/nothing.xml"}
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
{if $comment->getUType() === 1}
|
||||
{if $comment->getUType() === 1 && !is_null($comment->isLikedByUser())}
|
||||
<div class="post-menu">
|
||||
<strong>
|
||||
{if $comment->isLikedByUser()}
|
||||
|
|
|
@ -79,3 +79,39 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{/block}
|
||||
|
||||
{block actions}
|
||||
{if $x->getId() !== $thisUser->getId()}
|
||||
{var subStatus = $x->getSubscriptionStatus($thisUser)}
|
||||
{if $subStatus === 0}
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="add" />
|
||||
<input type="hidden" name="id" value="{$x->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" class="profile_link" value="{_"friends_add"}" />
|
||||
</form>
|
||||
{elseif $subStatus === 1}
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="add" />
|
||||
<input type="hidden" name="id" value="{$x->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" class="profile_link" value="{_"friends_accept"}" />
|
||||
</form>
|
||||
{elseif $subStatus === 2}
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="rem" />
|
||||
<input type="hidden" name="id" value="{$x->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" class="profile_link" value="{_"friends_reject"}" />
|
||||
</form>
|
||||
{elseif $subStatus === 3}
|
||||
<a href="/im?sel={$x->getId()}" class="profile_link">{_"send_message"}</a>
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="rem" />
|
||||
<input type="hidden" name="id" value="{$x->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" class="profile_link" value="{_"friends_delete"}" />
|
||||
</form>
|
||||
{/if}
|
||||
{/if}
|
||||
{/block}
|
||||
|
|
|
@ -49,23 +49,17 @@
|
|||
|
||||
{block description}
|
||||
{$x->getDescription()}
|
||||
{if $x->canBeModifiedBy($thisUser ?? NULL)}
|
||||
{var clubPinned = $thisUser->isClubPinned($x)}
|
||||
<table n:if="$clubPinned || $thisUser->getPinnedClubCount() <= 10">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top"><span class="nobold">{_actions}: </span></td>
|
||||
<td>
|
||||
<a href="/groups_pin?club={$x->getId()}&hash={rawurlencode($csrfToken)}" id="_pinGroup" data-group-name="{$x->getName()}" data-group-url="{$x->getUrl()}">
|
||||
{if $clubPinned}
|
||||
{_remove_from_left_menu}
|
||||
{else}
|
||||
{_add_to_left_menu}
|
||||
{/if}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{var clubPinned = $thisUser->isClubPinned($x)}
|
||||
{if $x->canBeModifiedBy($thisUser ?? NULL) || $clubPinned || $thisUser->getPinnedClubCount() <= 10}
|
||||
{block actions}
|
||||
<a class="profile_link" href="/groups_pin?club={$x->getId()}&hash={rawurlencode($csrfToken)}" id="_pinGroup" data-group-name="{$x->getName()}" data-group-url="{$x->getUrl()}">
|
||||
{if $clubPinned}
|
||||
{_remove_from_left_menu}
|
||||
{else}
|
||||
{_add_to_left_menu}
|
||||
{/if}
|
||||
</a>
|
||||
{/block}
|
||||
{/if}
|
|
@ -332,6 +332,7 @@
|
|||
|
||||
<div style="width: 75%; display: inline-block;">
|
||||
{presenter "openvk!Support->knowledgeBaseArticle", "points"}
|
||||
<center>{tr("also_you_can_transfer_points", $thisUser->getCoins(), rawurlencode($csrfToken))|noescape}</center>
|
||||
</div>
|
||||
<div style="width: 22%; float: right;">
|
||||
<p style="margin: 0; font-size: medium; text-align: center;">
|
||||
|
|
|
@ -91,25 +91,25 @@
|
|||
</a>
|
||||
{/if}
|
||||
|
||||
<a n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce']" href="/gifts?act=pick&user={$user->getId()}" class="profile_link">{_send_gift}</a>
|
||||
|
||||
<a n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && $user->getGiftCount() == 0" href="/gifts?act=pick&user={$user->getId()}" class="profile_link">{_send_gift}</a>
|
||||
|
||||
{var subStatus = $user->getSubscriptionStatus($thisUser)}
|
||||
{if $subStatus === 0}
|
||||
<form action="/setSub/user" method="post">
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="add" />
|
||||
<input type="hidden" name="id" value="{$user->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" class="profile_link" value="{_"friends_add"}" />
|
||||
</form>
|
||||
{elseif $subStatus === 1}
|
||||
<form action="/setSub/user" method="post">
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="add" />
|
||||
<input type="hidden" name="id" value="{$user->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<input type="submit" class="profile_link" value="{_"friends_accept"}" />
|
||||
</form>
|
||||
{elseif $subStatus === 2}
|
||||
<form action="/setSub/user" method="post">
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="rem" />
|
||||
<input type="hidden" name="id" value="{$user->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
|
@ -117,7 +117,7 @@
|
|||
</form>
|
||||
{elseif $subStatus === 3}
|
||||
<a href="/im?sel={$user->getId()}" class="profile_link">{_"send_message"}</a>
|
||||
<form action="/setSub/user" method="post">
|
||||
<form action="/setSub/user" method="post" class="profile_link_form">
|
||||
<input type="hidden" name="act" value="rem" />
|
||||
<input type="hidden" name="id" value="{$user->getId()}" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
|
@ -125,6 +125,7 @@
|
|||
</form>
|
||||
{/if}
|
||||
{/if}
|
||||
<a n:if="$user->getFollowersCount() > 0" href="/friends{$user->getId()}?act=incoming" class="profile_link">{tr("followers", $user->getFollowersCount())}</a>
|
||||
</div>
|
||||
<div n:if="isset($thisUser) && !$thisUser->prefersNotToSeeRating()" class="profile-hints">
|
||||
{var completeness = $user->getProfileCompletenessReport()}
|
||||
|
@ -150,39 +151,15 @@
|
|||
</a>
|
||||
<a n:if="in_array('telegram', $completeness->unfilled)" href="/edit?act=contacts">
|
||||
<img src="/assets/packages/static/openvk/img/icon2.gif" />
|
||||
Telegram (+10%)
|
||||
Telegram (+15%)
|
||||
</a>
|
||||
<a n:if="in_array('status', $completeness->unfilled)" href="/edit">
|
||||
<img src="/assets/packages/static/openvk/img/icon3.gif" />
|
||||
{_status} (+10%)
|
||||
{_status} (+15%)
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<br />
|
||||
<div n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && ($giftCount = $user->getGiftCount()) > 0">
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$giftCount});">
|
||||
{_gifts}
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_subtitle">
|
||||
{tr("gifts", $giftCount)}
|
||||
<div style="float:right;">
|
||||
<a href="/gifts{$user->getId()}">{_all_title}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ovk-avView">
|
||||
<div class="ovk-avView--el" n:foreach="$user->getGifts(1, 3) as $giftDescriptor">
|
||||
{var hideInfo = !is_null($thisUser) ? ($giftDescriptor->anon ? $thisUser->getId() !== $user->getId() : false) : false}
|
||||
|
||||
<a href="{$hideInfo ? 'javascript:false' : $giftDescriptor->sender->getURL()}">
|
||||
<img class="ava"
|
||||
src="{$giftDescriptor->gift->getImage(2)}"
|
||||
alt="{$hideInfo ? tr('gift') : ($giftDescriptor->caption ?? tr('gift'))}" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div n:if="$user->getFriendsCount() > 0 && $user->getPrivacyPermission('friends.read', $thisUser ?? NULL)">
|
||||
{var friendCount = $user->getFriendsCount()}
|
||||
|
||||
|
@ -196,37 +173,17 @@
|
|||
<a href="/friends{$user->getId()}">{_"all_title"}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ovk-avView">
|
||||
<div class="ovk-avView--el" n:foreach="$user->getFriends(1) as $friend">
|
||||
<a href="{$friend->getURL()}">
|
||||
<img class="ava" src="{$friend->getAvatarUrl()}" />
|
||||
</a>
|
||||
<br/>
|
||||
<a href="{$friend->getURL()}">{$friend->getFirstName()}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div n:if="$user->getFollowersCount() > 0">
|
||||
{var followersCount = $user->getFollowersCount()}
|
||||
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$followersCount});">
|
||||
{_followers}
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_subtitle">
|
||||
{tr("followers", $followersCount)}
|
||||
<div style="float:right;">
|
||||
<a href="/friends{$user->getId()}?act=incoming">{_"all_title"}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ovk-avView">
|
||||
<div class="ovk-avView--el" n:foreach="$user->getFollowers(1) as $follower">
|
||||
<a href="{$follower->getURL()}">
|
||||
<img class="ava" src="{$follower->getAvatarUrl()}" />
|
||||
</a>
|
||||
<br/>
|
||||
<a href="{$follower->getURL()}">{$follower->getFirstName()}</a>
|
||||
<div class="content_list">
|
||||
<div class="cl_element" n:foreach="$user->getFriends(1) as $friend">
|
||||
<div class="cl_avatar">
|
||||
<a href="{$friend->getURL()}">
|
||||
<img class="ava" src="{$friend->getAvatarUrl()}" />
|
||||
</a>
|
||||
</div>
|
||||
<a href="{$friend->getURL()}" class="cl_name">
|
||||
<text class="cl_fname">{$friend->getFirstName()}</text>
|
||||
<text class="cl_lname">{$friend->getLastName()}</text>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -508,6 +465,35 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div n:if="OPENVK_ROOT_CONF['openvk']['preferences']['commerce'] && ($giftCount = $user->getGiftCount()) > 0">
|
||||
<div class="content_title_expanded" onclick="hidePanel(this, {$giftCount});">
|
||||
{_gifts}
|
||||
</div>
|
||||
<div>
|
||||
<div class="content_subtitle">
|
||||
{tr("gifts", $giftCount)}
|
||||
<div style="float:right;">
|
||||
{if OPENVK_ROOT_CONF['openvk']['preferences']['commerce']}
|
||||
<a href="/gifts?act=pick&user={$user->getId()}">{_send_gift}</a> |
|
||||
{/if}
|
||||
<a href="/gifts{$user->getId()}">{_all_title}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_list long">
|
||||
<div class="cl_element" style="width: 25%;" n:foreach="$user->getGifts(1, 4) as $giftDescriptor">
|
||||
{var hideInfo = !is_null($thisUser) ? ($giftDescriptor->anon ? $thisUser->getId() !== $user->getId() : false) : false}
|
||||
<div class="cl_avatar">
|
||||
<a href="{$hideInfo ? 'javascript:false' : $giftDescriptor->sender->getURL()}">
|
||||
<img style="width: 70px; max-height: 70px;"
|
||||
src="{$giftDescriptor->gift->getImage(2)}"
|
||||
alt="{$hideInfo ? tr('gift') : ($giftDescriptor->caption ?? tr('gift'))}" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{presenter "openvk!Wall->wallEmbedded", $user->getId()}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
{if $comment->canBeDeletedBy($thisUser)}
|
||||
<a href="/comment{$comment->getId()}/delete">{_"delete"}</a> |
|
||||
{/if}
|
||||
<a class="comment-reply">Ответить</a>
|
||||
<a class="comment-reply">{_"reply"}</a>
|
||||
<div style="float: right; font-size: .7rem;">
|
||||
<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>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{var sender = $notification->getModel(1)}
|
||||
{var value = (int) explode(" ", $notification->getData(), 2)[0]}
|
||||
{var message = explode(" ", $notification->getData(), 2)[1]}
|
||||
|
||||
<a href="{$sender->getURL()}"><b>{$sender->getCanonicalName()}</b></a> {_transferred_to_you} {tr("points_amount", $value)}.
|
||||
{if !empty($message)}
|
||||
{_message}: "{$message}".
|
||||
{/if}
|
|
@ -10,7 +10,8 @@
|
|||
<td width="54" valign="top">
|
||||
<img
|
||||
src="{$author->getAvatarURL()}"
|
||||
width="{ifset $compact}25{else}50{/ifset}" />
|
||||
width="{ifset $compact}25{else}50{/ifset}"
|
||||
{ifset $compact}class="cCompactAvatars"{/ifset} />
|
||||
{if !$post->isPostedOnBehalfOfGroup() && !$compact}
|
||||
<span n:if="$author->isOnline()" class="post-online">
|
||||
{_online}
|
||||
|
|
|
@ -57,7 +57,7 @@ class Localizator
|
|||
$lang = is_null($lang) ? static::DEFAULT_LANG : $lang;
|
||||
$array = @self::parse(dirname(__FILE__) . "/../../locales/$lang.strings");
|
||||
|
||||
return $array[$id] ?? (!empty($array["__fallback"]) ? $this->_($id, $array["__fallback"]) : "@$id");
|
||||
return $array[$id] ?? "@$id";
|
||||
}
|
||||
|
||||
function export($lang = NULL): ?array
|
||||
|
|
|
@ -59,6 +59,8 @@ routes:
|
|||
handler: "User->twoFactorAuthSettings"
|
||||
- url: "/settings/2fa/disable"
|
||||
handler: "User->disableTwoFactorAuth"
|
||||
- url: "/coins_transfer"
|
||||
handler: "User->coinsTransfer"
|
||||
- url: "/id{num}"
|
||||
handler: "User->view"
|
||||
- url: "/friends{num}"
|
||||
|
|
|
@ -257,23 +257,29 @@ a {
|
|||
|
||||
.album-photo {
|
||||
position: relative;
|
||||
background-color: darkgrey;
|
||||
margin: 4pt;
|
||||
width: calc(33% - 10pt);
|
||||
height: 82px;
|
||||
width: 25%;
|
||||
max-height: 140px;
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
vertical-align: text-top;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.album-photo img {
|
||||
width: 100%;
|
||||
max-height: 82px;
|
||||
width: unset;
|
||||
max-height: 120px !important;
|
||||
max-width: 83%;
|
||||
vertical-align: top;
|
||||
border: 1px #ccc solid;
|
||||
padding: 8px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.album-photo > .album-photo--delete {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 5px;
|
||||
margin: 4px;
|
||||
color: #fff;
|
||||
|
@ -289,6 +295,11 @@ a {
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
.album-flex {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.name-checkmark {
|
||||
margin-left: 2pt;
|
||||
}
|
||||
|
@ -307,6 +318,10 @@ a {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.profile_link_form {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#profile_links {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
@ -315,6 +330,10 @@ a {
|
|||
background: #ECECEC;
|
||||
}
|
||||
|
||||
.action_links > .profile_link, .action_links > .profile_link_form > .profile_link {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.page_footer {
|
||||
margin-left: 95px;
|
||||
padding-top: 5px;
|
||||
|
@ -683,6 +702,44 @@ span {
|
|||
max-height: 63px;
|
||||
}
|
||||
|
||||
.content_list {
|
||||
display: flex;
|
||||
width: 200px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.content_list.long {
|
||||
width: 397px;
|
||||
}
|
||||
|
||||
.content_list .cl_element {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.content_list.long .cl_element {
|
||||
width: 16.5%;
|
||||
}
|
||||
|
||||
.content_list .cl_element .cl_avatar {
|
||||
padding: 7px 7px 0 7px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.content_list .cl_element .cl_name {
|
||||
padding: 0 3px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.content_list .cl_element .cl_name .cl_lname {
|
||||
font-size: 7pt;
|
||||
}
|
||||
|
||||
.ava {
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
table.User {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
@ -696,6 +753,10 @@ table.User {
|
|||
margin-bottom: -12px;
|
||||
}
|
||||
|
||||
.container_gray.bottom {
|
||||
border-bottom: #ebebeb solid 1px;
|
||||
}
|
||||
|
||||
#auth .container_gray {
|
||||
margin-left: -10px;
|
||||
margin-bottom: -10px;
|
||||
|
@ -1687,3 +1748,9 @@ body.scrolled .toTop:hover {
|
|||
border-bottom: #e6e6e6 solid 1px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.messagebox-content-header {
|
||||
background: #F7F7F7;
|
||||
margin: -20px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
|
|
@ -1,36 +1,37 @@
|
|||
function tr(string, ...arg) {
|
||||
function tr(string, ...args) {
|
||||
let output = window.lang[string];
|
||||
if(arg.length > 0) {
|
||||
if(typeof arg[0] == 'number') {
|
||||
let numberedStringId;
|
||||
let cardinal = arg[0];
|
||||
if(args.length > 0) {
|
||||
if(typeof args[0] === "number") {
|
||||
const cardinal = args[0];
|
||||
let numberedString;
|
||||
|
||||
switch(cardinal) {
|
||||
case 0:
|
||||
numberedString = string + '_zero';
|
||||
numberedString = string + "_zero";
|
||||
break;
|
||||
case 1:
|
||||
numberedString = string + '_one';
|
||||
numberedString = string + "_one";
|
||||
break;
|
||||
default:
|
||||
numberedString = string + (cardinal < 5 ? '_few' : '_other');
|
||||
numberedString = string + (cardinal < 5 ? "_few" : "_other");
|
||||
}
|
||||
|
||||
let newoutput = window.lang[numberedString];
|
||||
if(newoutput === null) {
|
||||
newoutput = window.lang[string + '_other'];
|
||||
if(newoutput === null) {
|
||||
newoutput = output;
|
||||
}
|
||||
}
|
||||
let newOutput = window.lang[numberedString];
|
||||
if(newOutput === null)
|
||||
newOutput = window.lang[string + "_other"];
|
||||
|
||||
output = newoutput;
|
||||
if(newOutput === null)
|
||||
newOutput = output;
|
||||
|
||||
output = newOutput;
|
||||
}
|
||||
}
|
||||
|
||||
let i = 1;
|
||||
arg.forEach(element => {
|
||||
output = output.replace(RegExp('(\\$' + i + ')'), element);
|
||||
i++;
|
||||
});
|
||||
|
||||
if(output == null)
|
||||
return "@" + string;
|
||||
|
||||
for(const [ i, element ] of Object.entries(args))
|
||||
output = output.replace(RegExp("(\\$" + (Number(i) + 1) + ")"), element);
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -171,3 +171,49 @@ function setClubAdminComment(clubId, adminId, hash) {
|
|||
Function.noop
|
||||
]);
|
||||
}
|
||||
|
||||
function showCoinsTransferDialog(coinsCount, hash) {
|
||||
MessageBox(tr("transfer_poins"), `
|
||||
<div class="messagebox-content-header">
|
||||
${tr("points_transfer_dialog_header_1")}
|
||||
${tr("points_transfer_dialog_header_2")} <b>${tr("points_amount", coinsCount)}</b>
|
||||
</div>
|
||||
<form action="/coins_transfer" method="post" id="coins_transfer_form" style="margin-top: 30px">
|
||||
<table cellspacing="7" cellpadding="0" border="0" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">${tr("receiver_address")}:</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="receiver" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">${tr("coins_count")}:</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="value" style="width: 100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top">
|
||||
<span class="nobold">${tr("message")}:</span>
|
||||
</td>
|
||||
<td>
|
||||
<textarea name="message" style="width: 100%;"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="hidden" name="hash" value="${hash}" />
|
||||
</form>
|
||||
`, [tr("transfer_poins_button"), tr("cancel")], [
|
||||
() => {
|
||||
document.querySelector("#coins_transfer_form").submit();
|
||||
},
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ composer2 install
|
|||
|
||||
```bash
|
||||
cd ..
|
||||
git clone --recursive https://github.com/openvk/openvk.git
|
||||
git clone https://github.com/openvk/openvk.git
|
||||
cd openvk/
|
||||
composer2 install
|
||||
cd Web/static/js
|
||||
|
|
1
install/sqls/00016-place-oftopic-list-setting.sql
Normal file
1
install/sqls/00016-place-oftopic-list-setting.sql
Normal file
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `groups` ADD COLUMN `display_topics_above_wall` BOOLEAN NOT NULL DEFAULT FALSE AFTER `everyone_can_create_topics`;
|
|
@ -1,3 +1,5 @@
|
|||
#include <en>
|
||||
|
||||
"__locale" = "hy_AM.utf8;hy_AM.UTF-8;Arm";
|
||||
"__WinEncoding" = "Windows-1251";
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "be_BY.UTF-8;Bel";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "be_BY@latin;Bel_Lat";
|
||||
"__WinEncoding" = "Windows-1251";
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <en>
|
||||
|
||||
"__locale" = "de_DE.UTF-8;Deu";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -179,6 +179,8 @@
|
|||
"open_post" = "Open post";
|
||||
"version_incompatibility" = "This attachment could not be displayed. Probably the database is incompatible with the current version of OpenVK.";
|
||||
|
||||
"reply" = "Reply";
|
||||
|
||||
/* Friends */
|
||||
|
||||
"friends" = "Friends";
|
||||
|
@ -522,6 +524,31 @@
|
|||
"usages_total" = "Number of uses";
|
||||
"usages_left" = "Uses left";
|
||||
|
||||
"points_transfer_dialog_header_1" = "You can send as a gift or transfer part of the votes to another person.";
|
||||
"points_transfer_dialog_header_2" = "Your current balance:";
|
||||
|
||||
"points_amount_one" = "1 vote";
|
||||
"points_amount_other" = "$1 votes";
|
||||
|
||||
"transfer_poins" = "Transfer votes";
|
||||
"transfer_poins_button" = "Transfer votes";
|
||||
"also_you_can_transfer_points" = "You can also <a href=\"javascript:showCoinsTransferDialog($1, '$2')\">transfer votes</a> to another person.";
|
||||
|
||||
"transferred_to_you" = "transferred to you";
|
||||
|
||||
"receiver_address" = "Receiver address";
|
||||
"coins_count" = "Number of votes";
|
||||
"message" = "Message";
|
||||
|
||||
"failed_to_tranfer_points" = "Failed to transfer votes";
|
||||
|
||||
"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.";
|
||||
"negative_transfer_value" = "We cannot steal votes from another person, sorry.";
|
||||
"message_is_too_long" = "The message is too long.";
|
||||
"receiver_not_found" = "The receiver was not found.";
|
||||
"you_dont_have_enough_points" = "You don't have enough votes.";
|
||||
|
||||
/* Gifts */
|
||||
|
||||
"gift" = "Gift";
|
||||
|
@ -641,6 +668,7 @@
|
|||
"created" = "Created";
|
||||
|
||||
"everyone_can_create_topics" = "Everyone can create topics";
|
||||
"display_list_of_topics_above_wall" = "Display a list of topics above the wall";
|
||||
|
||||
"topic_changes_saved_comment" = "The updated title and settings will appear on the topic page.";
|
||||
|
||||
|
@ -724,6 +752,10 @@
|
|||
"paginator_page" = "Page $1";
|
||||
"paginator_next" = "Next";
|
||||
|
||||
/* About */
|
||||
|
||||
"about_openvk" = "About OpenVK";
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
"ok" = "OK";
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <en>
|
||||
|
||||
"__locale" = "eo.utf8";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "kk_KZ.UTF-8;Kaz";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <en>
|
||||
|
||||
"__locale" = "pl_PL.utf8;pl_PL.UTF-8;Pol";
|
||||
"__WinEncoding" = "Windows-1251";
|
||||
|
||||
|
|
|
@ -182,6 +182,8 @@
|
|||
"open_post" = "Открыть запись";
|
||||
"version_incompatibility" = "Не удалось отобразить это вложение. Возможно, база данных несовместима с текущей версией OpenVK.";
|
||||
|
||||
"reply" = "Ответить";
|
||||
|
||||
/* Friends */
|
||||
|
||||
"friends" = "Друзья";
|
||||
|
@ -544,6 +546,33 @@
|
|||
"usages_total" = "Количество использований";
|
||||
"usages_left" = "Осталось использований";
|
||||
|
||||
"points_transfer_dialog_header_1" = "Вы можете отправить в подарок или передать часть голосов другому человеку.";
|
||||
"points_transfer_dialog_header_2" = "Ваш текущий баланс:";
|
||||
|
||||
"points_amount_one" = "1 голос";
|
||||
"points_amount_few" = "$1 голоса";
|
||||
"points_amount_many" = "$1 голосов";
|
||||
"points_amount_other" = "$1 голосов";
|
||||
|
||||
"transfer_poins" = "Передача голосов";
|
||||
"transfer_poins_button" = "Передать голоса";
|
||||
"also_you_can_transfer_points" = "Также вы можете <a href=\"javascript:showCoinsTransferDialog($1, '$2')\">передать голоса</a> другому человеку.";
|
||||
|
||||
"transferred_to_you" = "передал вам";
|
||||
|
||||
"receiver_address" = "Адрес получателя";
|
||||
"coins_count" = "Количество голосов";
|
||||
"message" = "Сообщение";
|
||||
|
||||
"failed_to_tranfer_points" = "Не удалось передать голоса";
|
||||
|
||||
"points_transfer_successful" = "Вы успешно передали <b>$1 <a href=\"$2\">$3</a></b>.";
|
||||
"not_all_information_has_been_entered" = "Введена не вся информация.";
|
||||
"negative_transfer_value" = "Мы не можем украсть голоса у другого человека, извините.";
|
||||
"message_is_too_long" = "Сообщение слишком длинное.";
|
||||
"receiver_not_found" = "Получатель не найден.";
|
||||
"you_dont_have_enough_points" = "У вас недостаточно голосов.";
|
||||
|
||||
/* Gifts */
|
||||
|
||||
"gift" = "Подарок";
|
||||
|
@ -674,6 +703,7 @@
|
|||
"created" = "Создано";
|
||||
|
||||
"everyone_can_create_topics" = "Все могут создавать темы";
|
||||
"display_list_of_topics_above_wall" = "Отображать список тем над стеной";
|
||||
|
||||
"topic_changes_saved_comment" = "Обновлённый заголовок и настройки появятся на странице с темой.";
|
||||
|
||||
|
@ -757,6 +787,10 @@
|
|||
"paginator_page" = "Страница $1";
|
||||
"paginator_next" = "Дальше";
|
||||
|
||||
/* About */
|
||||
|
||||
"about_openvk" = "Об OpenVK";
|
||||
|
||||
/* Dialogs */
|
||||
|
||||
"ok" = "ОК";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "ru_UA.utf8;ru_RU.UTF-8;Rus";
|
||||
"__WinEncoding" = "Windows-1251";
|
||||
"__fallback" = "ru";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "sr_CS.UTF-8;Srb";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <en>
|
||||
|
||||
"__locale" = "sr_CS.UTF-8;Srb_Latin";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <en>
|
||||
|
||||
"__locale" = "tr_TR.UTF-8;Tur";
|
||||
|
||||
/* Check for https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <ru>
|
||||
|
||||
"__locale" = "uk_UA.utf8;Ukr";
|
||||
"__WinEncoding" = "Windows-1251";
|
||||
|
||||
|
|
Loading…
Reference in a new issue