Groups: Allow adding comments to group admins (#274 from @maksalees)

This commit is contained in:
Vladimir Barinov 2021-11-06 18:09:30 +03:00 committed by GitHub
commit 7b17328399
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 172 additions and 52 deletions

View file

@ -89,6 +89,11 @@ class Club extends RowModel
{ {
return (new Users)->get($this->getRecord()->owner); return (new Users)->get($this->getRecord()->owner);
} }
function getOwnerComment(): string
{
return is_null($this->getRecord()->owner_comment) ? "" : $this->getRecord()->owner_comment;
}
function getDescription(): ?string function getDescription(): ?string
{ {
@ -268,18 +273,6 @@ class Club extends RowModel
{ {
$rels = $this->getRecord()->related("group_coadmins.club")->page($page, 6); $rels = $this->getRecord()->related("group_coadmins.club")->page($page, 6);
foreach($rels as $rel) {
$rel = (new Users)->get($rel->user);
if(!$rel) continue;
yield $rel;
}
}
function getManagersWithComment(int $page = 1): \Traversable
{
$rels = $this->getRecord()->related("group_coadmins.club")->where("comment IS NOT NULL")->page($page, 10);
foreach($rels as $rel) { foreach($rels as $rel) {
$rel = (new Managers)->get($rel->id); $rel = (new Managers)->get($rel->id);
if(!$rel) continue; if(!$rel) continue;
@ -287,16 +280,16 @@ class Club extends RowModel
yield $rel; yield $rel;
} }
} }
function getManager(User $user): ?Manager
{
return (new Managers)->getByUserAndClub($user->getId(), $this->getId());
}
function getManagersCount(): int function getManagersCount(): int
{ {
return sizeof($this->getRecord()->related("group_coadmins.club")) + 1; return sizeof($this->getRecord()->related("group_coadmins.club")) + 1;
} }
function getManagersCountWithComment(): int
{
return sizeof($this->getRecord()->related("group_coadmins.club")->where("comment IS NOT NULL")) + 1;
}
function addManager(User $user, ?string $comment = NULL): void function addManager(User $user, ?string $comment = NULL): void
{ {

View file

@ -17,7 +17,7 @@ class Manager extends RowModel
return $this->getRecord()->id; return $this->getRecord()->id;
} }
function getUserId(): string function getUserId(): int
{ {
return $this->getRecord()->user; return $this->getRecord()->user;
} }
@ -27,7 +27,7 @@ class Manager extends RowModel
return (new Users)->get($this->getRecord()->user); return (new Users)->get($this->getRecord()->user);
} }
function getClubId(): string function getClubId(): int
{ {
return $this->getRecord()->club; return $this->getRecord()->club;
} }

View file

@ -98,6 +98,7 @@ final class GroupPresenter extends OpenVKPresenter
{ {
$user = is_null($this->queryParam("user")) ? $this->postParam("user") : $this->queryParam("user"); $user = is_null($this->queryParam("user")) ? $this->postParam("user") : $this->queryParam("user");
$comment = $this->postParam("comment"); $comment = $this->postParam("comment");
$removeComment = $this->postParam("removeComment") === "1";
//$index = $this->queryParam("index"); //$index = $this->queryParam("index");
if(!$user) if(!$user)
$this->badRequest(); $this->badRequest();
@ -110,16 +111,34 @@ final class GroupPresenter extends OpenVKPresenter
if(!$club->canBeModifiedBy($this->user->identity ?? NULL) && $club->getOwner()->getId() !== $user->getId()) if(!$club->canBeModifiedBy($this->user->identity ?? NULL) && $club->getOwner()->getId() !== $user->getId())
$this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс."); $this->flashFail("err", "Ошибка доступа", "У вас недостаточно прав, чтобы изменять этот ресурс.");
/* if(!empty($index)){ if($removeComment) {
$manager = (new Managers)->get($index); if($club->getOwner()->getId() == $user->getId()) {
$manager->setComment($comment); $club->setOwner_Comment(null);
$club->save();
} else {
$manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId());
$manager->setComment(null);
$manager->save();
}
$this->flashFail("succ", "Операция успешна", "Комментарий к администратору удален");
} elseif($comment) {
if(strlen($comment) > 36) {
$commentLength = (string) strlen($comment);
$this->flashFail("err", "Ошибка", "Комментарий слишком длинный ($commentLength символов вместо 36 символов)");
return;
}
if($club->getOwner()->getId() == $user->getId()) {
$club->setOwner_Comment($comment);
$club->save();
} else {
$manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId());
$manager->setComment($comment);
$manager->save();
}
$this->flashFail("succ", "Операция успешна", "Комментарий к администратору изменён"); $this->flashFail("succ", "Операция успешна", "Комментарий к администратору изменён");
}else{ */
if($comment) {
$manager = (new Managers)->getByUserAndClub($user->getId(), $club->getId());
$manager->setComment($comment);
$manager->save();
$this->flashFail("succ", "Операция успешна", ".");
}else{ }else{
if($club->canBeModifiedBy($user)) { if($club->canBeModifiedBy($user)) {
$club->removeManager($user); $club->removeManager($user);

View file

@ -46,16 +46,36 @@
{$club->canBeModifiedBy($x) ? tr("administrator") : tr("follower")} {$club->canBeModifiedBy($x) ? tr("administrator") : tr("follower")}
</td> </td>
</tr> </tr>
<tr n:if="$club->canBeModifiedBy($thisUser ?? NULL) && $club->getOwner()->getId() !== $x->getId()"> {var manager = $club->getManager($x)}
<tr n:if="$manager && !empty($manager->getComment()) || $club->getOwner()->getId() === $x->getId() && !empty($club->getOwnerComment())">
<td width="120" valign="top"><span class="nobold">{_comment}: </span></td>
<td>
{if $club->getOwner()->getId() === $x->getId()}
{$club->getOwnerComment()}
{else}
{$manager->getComment()}
{/if}
</td>
</tr>
<tr n:if="$club->canBeModifiedBy($thisUser ?? NULL) && $club->getOwner()->getId() !== $x->getId() || $club->getOwner()->getId() == $x->getId()">
<td width="120" valign="top"><span class="nobold">{_actions}: </span></td> <td width="120" valign="top"><span class="nobold">{_actions}: </span></td>
<td> <td>
<a href="/club{$club->getId()}/setAdmin.jsp?user={$x->getId()}&hash={rawurlencode($csrfToken)}"> <a href="/club{$club->getId()}/setAdmin.jsp?user={$x->getId()}&hash={rawurlencode($csrfToken)}" n:if="$club->getOwner()->getId() !== $x->getId()">
{if $club->canBeModifiedBy($x)} {if $manager}
{_devote} {_devote}
{else} {else}
{_promote_to_admin} {_promote_to_admin}
{/if} {/if}
</a> </a>
{if $manager}
|
<a href="javascript:setClubAdminComment('{$club->getId()}', '{$manager->getUserId()}', '{rawurlencode($csrfToken)}')">
{_set_comment}
</a>
{/if}
<a n:if="$club->getOwner()->getId() === $x->getId()" href="javascript:setClubAdminComment('{$club->getId()}', '{$club->getOwner()->getId()}', '{rawurlencode($csrfToken)}')">
{_set_comment}
</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View file

@ -109,33 +109,56 @@
<div class="content_title_expanded" onclick="hidePanel(this);"> <div class="content_title_expanded" onclick="hidePanel(this);">
{_"creator"} {_"creator"}
</div> </div>
<div style="padding:4px"> <div class="avatar-list-item" style="padding: 8px;">
{var author = $club->getOwner()} {var author = $club->getOwner()}
<ul> <div class="avatar">
<li> <a href="{$author->getURL()}">
<a href="{$author->getURL()}"><b>{$author->getCanonicalName()}</b></a> <img class="ava" src="{$author->getAvatarUrl()}" />
</li> </a>
</ul> </div>
<div class="info info-without-subtitle-centered" n:if="empty($club->getOwnerComment())">
<a href="{$author->getURL()}" class="title">{$author->getCanonicalName()}</a>
</div>
<div class="info" n:if="!empty($club->getOwnerComment())">
<a href="{$author->getURL()}" class="title">{$author->getCanonicalName()}</a>
<div class="subtitle">{$club->getOwnerComment()}</div>
</div>
</div> </div>
</div> </div>
<div n:if="$club->getAdministratorsListDisplay() == 1"> <div n:if="$club->getAdministratorsListDisplay() == 1">
<div class="content_title_expanded" onclick="hidePanel(this);"> <div class="content_title_expanded" onclick="hidePanel(this);">
{_"administrators"} {_"administrators"}
</div> </div>
<div style="padding:4px"> <div>
{var author = $club->getOwner()} <div class="content_subtitle">
<ul> {tr("administrators", $club->getManagersCount() + 1)}
<li> </div>
<a href="{$author->getURL()}"><b>{$author->getCanonicalName()}</b></a> <div class="avatar-list">
</li> <div class="avatar-list-item">
<li n:foreach="$club->getManagers(1) as $manager"> {var author = $club->getOwner()}
<a href="{$manager->getURL()}"><b>{$manager->getCanonicalName()}</b></a> <div class="avatar">
</li> <a href="{$author->getURL()}">
{var managersCount = $club->getManagersCount()} <img class="ava" src="{$author->getAvatarUrl()}" />
<li n:if="$managersCount > 7"> </a>
<b>{tr("and_more", $managersCount - 7)}</b> </div>
</li> <div class="info">
</ul> <a href="{$author->getURL()}" class="title">{$author->getCanonicalName()}</a>
<div class="subtitle" n:if="!empty($club->getOwnerComment())">{$club->getOwnerComment()}</div>
</div>
</div>
<div class="avatar-list-item" n:foreach="$club->getManagers(1) as $manager">
{var user = $manager->getUser()}
<div class="avatar">
<a href="{$user->getURL()}">
<img height="32" class="ava" src="{$user->getAvatarUrl()}" />
</a>
</div>
<div class="info">
<a href="{$user->getURL()}" class="title">{$user->getCanonicalName()}</a>
<div class="subtitle" n:if="!empty($manager->getComment())">{$manager->getComment()}</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div n:if="$albumsCount > 0"> <div n:if="$albumsCount > 0">

View file

@ -1450,3 +1450,47 @@ body.scrolled .toTop:hover {
.knowledgeBaseArticle { .knowledgeBaseArticle {
margin-top: -11px; /* this is very stupid fix but nah */ margin-top: -11px; /* this is very stupid fix but nah */
} }
.avatar-list {
padding: 4px 8px 4px 8px;
}
.avatar-list-item {
padding: 4px 0 4px 0;
}
.avatar-list-item::after {
content: '.';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.avatar-list-item .avatar {
float: left;
}
.avatar-list-item .avatar img {
width: 32px;
height: 32px;
object-fit: cover;
}
.avatar-list-item .info {
float: left;
padding-left: 8px;
}
.avatar-list-item .info-without-subtitle-centered {
padding-top: 8px;
}
.avatar-list-item .info .title {
font-size: 11px;
}
.avatar-list-item .info .subtitle {
color: rgb(128, 128, 128);
font-size: 10px;
}

View file

@ -105,3 +105,23 @@ function repostPost(id, hash) {
Function.noop Function.noop
]); ]);
} }
function setClubAdminComment(clubId, adminId, hash) {
MessageBox("Изменить комментарий к администратору", `
<form action="/club${clubId}/setAdmin.jsp" method="post" id="uClubAdminCommentForm_${clubId}_${adminId}">
<input type="hidden" name="user" value="${adminId}">
<input type="hidden" name="hash" value="${hash}">
<input type="hidden" name="removeComment" id="uClubAdminCommentRemoveCommentInput_${clubId}_${adminId}" value="0">
<textarea name="comment" id="uClubAdminCommentTextArea_${clubId}_${adminId}"></textarea><br><br>
</form>
`, ["Изменить", "Отменить"], [
() => {
if (document.querySelector(`#uClubAdminCommentTextArea_${clubId}_${adminId}`).value === "") {
document.querySelector(`#uClubAdminCommentRemoveCommentInput_${clubId}_${adminId}`).value = "1";
}
document.querySelector(`#uClubAdminCommentForm_${clubId}_${adminId}`).submit();
},
Function.noop
]);
}

View file

@ -0,0 +1 @@
ALTER TABLE groups ADD COLUMN owner_comment VARCHAR(36) AFTER owner;

@ -1 +1 @@
Subproject commit 81c1e5a61af79bc661c6fe34974c73c99b262038 Subproject commit ef1b7ab803b56a02df670d91d7c22b3e509e6779