mirror of
https://github.com/openvk/openvk
synced 2025-03-04 00:29:57 +03:00
add liked content
This commit is contained in:
parent
a88e929717
commit
df0bb41276
12 changed files with 247 additions and 3 deletions
|
@ -558,6 +558,7 @@ class User extends RowModel
|
|||
"poster",
|
||||
"apps",
|
||||
"docs",
|
||||
"fave",
|
||||
],
|
||||
])->get($id);
|
||||
}
|
||||
|
@ -1195,6 +1196,7 @@ class User extends RowModel
|
|||
"poster",
|
||||
"apps",
|
||||
"docs",
|
||||
"fave",
|
||||
],
|
||||
])->set($id, (int) $status)->toInteger();
|
||||
|
||||
|
|
48
Web/Models/Repositories/Faves.php
Normal file
48
Web/Models/Repositories/Faves.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Repositories;
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
use openvk\Web\Models\Entities\User;
|
||||
use Nette\Database\Table\ActiveRow;
|
||||
|
||||
class Faves
|
||||
{
|
||||
private $context;
|
||||
private $likes;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->context = DatabaseConnection::i()->getContext();
|
||||
$this->likes = $this->context->table("likes");
|
||||
}
|
||||
|
||||
private function fetchLikes(User $user, string $class = 'Post')
|
||||
{
|
||||
$fetch = $this->likes->where([
|
||||
"model" => "openvk\\Web\\Models\\Entities\\".$class,
|
||||
"origin" => $user->getRealId(),
|
||||
]);
|
||||
|
||||
return $fetch;
|
||||
}
|
||||
|
||||
function fetchLikesSection(User $user, string $class = 'Post', int $page = 1, ?int $perPage = NULL): \Traversable
|
||||
{
|
||||
$perPage ??= OPENVK_DEFAULT_PER_PAGE;
|
||||
$fetch = $this->fetchLikes($user, $class)->page($page, $perPage);
|
||||
foreach($fetch as $like) {
|
||||
$className = "openvk\\Web\\Models\\Repositories\\".$class."s";
|
||||
$repo = new $className;
|
||||
if(!$repo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$entity = $repo->get($like->target);
|
||||
yield $entity;
|
||||
}
|
||||
}
|
||||
|
||||
function fetchLikesSectionCount(User $user, string $class = 'Post')
|
||||
{
|
||||
return $this->fetchLikes($user, $class)->count();
|
||||
}
|
||||
}
|
|
@ -373,6 +373,7 @@ final class GroupPresenter extends OpenVKPresenter
|
|||
public function renderDeleteAvatar(int $id)
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->assertNoCSRF();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
$club = $this->clubs->get($id);
|
||||
|
|
|
@ -9,7 +9,7 @@ use openvk\Web\Util\Sms;
|
|||
use openvk\Web\Themes\Themepacks;
|
||||
use openvk\Web\Models\Entities\{Photo, Post, EmailChangeVerification};
|
||||
use openvk\Web\Models\Entities\Notifications\{CoinsTransferNotification, RatingUpNotification};
|
||||
use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Videos, Notes, Vouchers, EmailChangeVerifications, Audios};
|
||||
use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Videos, Notes, Vouchers, EmailChangeVerifications, Audios, Faves};
|
||||
use openvk\Web\Models\Exceptions\InvalidUserNameException;
|
||||
use openvk\Web\Util\Validator;
|
||||
use Chandler\Security\Authenticator;
|
||||
|
@ -474,6 +474,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
public function renderDeleteAvatar()
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->assertNoCSRF();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
$avatar = $this->user->identity->getAvatarPhoto();
|
||||
|
@ -666,6 +667,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
"menu_standardo" => "poster",
|
||||
"menu_aplikoj" => "apps",
|
||||
"menu_doxc" => "docs",
|
||||
"menu_feva" => "fave",
|
||||
];
|
||||
foreach ($settings as $checkbox => $setting) {
|
||||
$user->setLeftMenuItemStatus($setting, $this->checkbox($checkbox));
|
||||
|
@ -942,4 +944,65 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$this->redirect("/settings");
|
||||
}
|
||||
}
|
||||
|
||||
function renderFave(): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
|
||||
$page = (int)($this->queryParam("p") ?? 1);
|
||||
$section = $this->queryParam("section") ?? "posts";
|
||||
$display_section = "posts";
|
||||
$data = NULL;
|
||||
$count = 0;
|
||||
|
||||
switch($section) {
|
||||
default:
|
||||
$this->notFound();
|
||||
break;
|
||||
case 'wall':
|
||||
case 'post':
|
||||
case 'posts':
|
||||
$data = (new Faves)->fetchLikesSection($this->user->identity, 'Post', $page);
|
||||
$count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Post');
|
||||
$display_section = "posts";
|
||||
break;
|
||||
case 'comment':
|
||||
case 'comments':
|
||||
$data = (new Faves)->fetchLikesSection($this->user->identity, 'Comment', $page);
|
||||
$count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Comment');
|
||||
$display_section = "comments";
|
||||
break;
|
||||
case 'photo':
|
||||
case 'photos':
|
||||
$data = (new Faves)->fetchLikesSection($this->user->identity, 'Photo', $page);
|
||||
$count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Photo');
|
||||
$display_section = "photos";
|
||||
break;
|
||||
case 'video':
|
||||
case 'videos':
|
||||
$data = (new Faves)->fetchLikesSection($this->user->identity, 'Video', $page);
|
||||
$count = (new Faves)->fetchLikesSectionCount($this->user->identity, 'Video');
|
||||
$display_section = "videos";
|
||||
break;
|
||||
}
|
||||
|
||||
$this->template->data = iterator_to_array($data);
|
||||
$this->template->count = $count;
|
||||
$this->template->page = $page;
|
||||
$this->template->perPage = OPENVK_DEFAULT_PER_PAGE;
|
||||
$this->template->section = $display_section;
|
||||
|
||||
$this->template->paginatorConf = (object) [
|
||||
"page" => $page,
|
||||
"count" => $count,
|
||||
"amount" => sizeof($this->template->data),
|
||||
"perPage" => $this->template->perPage,
|
||||
"atBottom" => false,
|
||||
"tidy" => true,
|
||||
'pageCount' => ceil($count / $this->template->perPage),
|
||||
];
|
||||
$this->template->extendedPaginatorConf = clone $this->template->paginatorConf;
|
||||
$this->template->extendedPaginatorConf->space = 11;
|
||||
$this->template->paginatorConf->atTop = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,10 +198,11 @@
|
|||
</a>
|
||||
<a href="/settings" class="link">{_my_settings}</a>
|
||||
|
||||
{if $thisUser->getLeftMenuItemStatus('docs') || $thisUser->getLeftMenuItemStatus('apps')}
|
||||
{if $thisUser->getLeftMenuItemStatus('docs') || $thisUser->getLeftMenuItemStatus('apps') || $thisUser->getLeftMenuItemStatus('fave')}
|
||||
<div class="menu_divider"></div>
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('apps')" href="/apps?act=installed" class="link">{_apps}</a>
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('docs')" href="/docs" class="link">{_my_documents}</a>
|
||||
<a n:if="$thisUser->getLeftMenuItemStatus('fave')" href="/fave" class="link">{_bookmarks_tab}</a>
|
||||
{/if}
|
||||
|
||||
{var $canAccessAdminPanel = $thisUser->getChandlerUser()->can("access")->model("admin")->whichBelongsTo(NULL)}
|
||||
|
|
80
Web/Presenters/templates/User/Fave.xml
Normal file
80
Web/Presenters/templates/User/Fave.xml
Normal file
|
@ -0,0 +1,80 @@
|
|||
{extends "../@layout.xml"}
|
||||
|
||||
{block title}{_bookmarks_tab}{/block}
|
||||
|
||||
{block header}
|
||||
{_bookmarks_tab}
|
||||
{/block}
|
||||
|
||||
{block wrap}
|
||||
<div class="wrap2">
|
||||
<div class="wrap1">
|
||||
<div class="page_wrap">
|
||||
<div class='summaryBar summaryBarFlex padding'>
|
||||
<div class='summary'>
|
||||
<b>{tr("faves", $count)} {*tr("showing_x_y", $page, $count)*}</b>
|
||||
</div>
|
||||
|
||||
{include "../components/paginator.xml", conf => $paginatorConf}
|
||||
</div>
|
||||
|
||||
<div class='page_wrap_content' id='search_page'>
|
||||
<div n:class='page_wrap_content_main, scroll_container, ($section == "photos" && $count > 0) ? album-flex'>
|
||||
<style>
|
||||
.scroll_node:first-of-type .comment {
|
||||
border-top: unset;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.scroll_node:last-of-type .post {
|
||||
border-bottom: unset;
|
||||
}
|
||||
|
||||
.content_page_error {
|
||||
min-height: 400px;
|
||||
}
|
||||
</style>
|
||||
{if $count > 0}
|
||||
{foreach $data as $dat}
|
||||
{if $section == "posts"}
|
||||
<div class="scroll_node">
|
||||
{include "../components/post.xml", post => $dat, commentSection => true}
|
||||
</div>
|
||||
{elseif $section == "comments"}
|
||||
<div class="scroll_node">
|
||||
{include "../components/comment.xml", comment => $dat, correctLink => true, no_reply_button => true}
|
||||
</div>
|
||||
{elseif $section == "photos"}
|
||||
<div class="album-photo scroll_node" onclick="OpenMiniature(event, {$dat->getURLBySizeId('larger')}, null, {$dat->getPrettyId()}, null)">
|
||||
<a href="/photo{$dat->getPrettyId()}">
|
||||
<img class="album-photo--image" src="{$dat->getURLBySizeId('tinier')}" alt="{$dat->getDescription()}" loading="lazy" />
|
||||
</a>
|
||||
</div>
|
||||
{elseif $section == "videos"}
|
||||
<div class="scroll_node">
|
||||
{include "../components/video.xml", video => $dat}
|
||||
</div>
|
||||
{/if}
|
||||
{/foreach}
|
||||
{else}
|
||||
{include "../components/content_error.xml", description => tr("faves_".$section."_empty_tip")}
|
||||
{/if}
|
||||
</div>
|
||||
<div class='page_wrap_content_options verticalGrayTabsWrapper'>
|
||||
<div class="page_wrap_content_options_list verticalGrayTabs with_padding">
|
||||
<a n:attr="id => $section === 'posts' ? 'used'" href="/fave?section=posts">{_s_posts}</a>
|
||||
<a n:attr="id => $section === 'comments' ? 'used'" href="/fave?section=comments">{_s_comments}</a>
|
||||
<a n:attr="id => $section === 'photos' ? 'used'" href="/fave?section=photos">{_s_photos}</a>
|
||||
<a n:attr="id => $section === 'videos' ? 'used'" href="/fave?section=videos">{_s_videos}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div n:if='$paginatorConf->pageCount > 1' class='page_content_paginator_bottom'>
|
||||
{include "../components/paginator.xml", conf => $extendedPaginatorConf}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
|
@ -696,6 +696,17 @@
|
|||
<span class="nobold">{_my_documents}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" valign="top" align="right" align="right">
|
||||
<input
|
||||
n:attr="checked => $user->getLeftMenuItemStatus('fave')"
|
||||
type="checkbox"
|
||||
name="menu_feva" />
|
||||
</td>
|
||||
<td>
|
||||
<span class="nobold">{_bookmarks_tab}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr n:if="sizeof(OPENVK_ROOT_CONF['openvk']['preferences']['menu']['links']) > 0">
|
||||
<td width="120" valign="top" align="right" align="right">
|
||||
<input
|
||||
|
|
|
@ -60,8 +60,9 @@
|
|||
<a href="javascript:reportComment({$comment->getId()})">{_report}</a>
|
||||
{/if}
|
||||
<div style="float: right; font-size: .7rem;">
|
||||
{var $isLiked = $comment->hasLikeFrom($thisUser)}
|
||||
<a class="post-like-button" href="/comment{$comment->getId()}/like?hash={rawurlencode($csrfToken)}" data-likes='{$likesCount}' data-id="1_{$comment->getPrettyId()}" data-type='comment'>
|
||||
<div class="heart" style="{if $comment->hasLikeFrom($thisUser)}opacity: 1;{else}opacity: 0.4;{/if}"></div>
|
||||
<div class="heart" n:attr="id => $isLiked ? liked" style="{if $isLiked}opacity: 1;{else}opacity: 0.4;{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -54,5 +54,6 @@ services:
|
|||
- openvk\Web\Models\Repositories\BannedLinks
|
||||
- openvk\Web\Models\Repositories\ChandlerGroups
|
||||
- openvk\Web\Models\Repositories\Documents
|
||||
- openvk\Web\Models\Repositories\Faves
|
||||
- openvk\Web\Presenters\MaintenancePresenter
|
||||
- openvk\Web\Presenters\NoSpamPresenter
|
||||
|
|
|
@ -413,6 +413,8 @@ routes:
|
|||
handler: "InternalAPI->getPostTemplate"
|
||||
- url: "/tour"
|
||||
handler: "About->tour"
|
||||
- url: "/fave"
|
||||
handler: "User->fave"
|
||||
- url: "/{?shortCode}"
|
||||
handler: "UnknownTextRouteStrategy->delegate"
|
||||
placeholders:
|
||||
|
|
|
@ -641,6 +641,8 @@
|
|||
"my_feed" = "My Feed";
|
||||
"my_feedback" = "My Feedback";
|
||||
"my_settings" = "My Settings";
|
||||
"bookmarks" = "Bookmarks";
|
||||
"bookmarks_tab" = "Saved";
|
||||
"bug_tracker" = "Bug Tracker";
|
||||
|
||||
"menu_settings" = "Settings";
|
||||
|
@ -2113,6 +2115,7 @@
|
|||
"s_apps" = "Applications";
|
||||
"s_posts" = "Posts";
|
||||
"s_comments" = "Comments";
|
||||
"s_photos" = "Photos";
|
||||
"s_videos" = "Videos";
|
||||
"s_audios" = "Music";
|
||||
"s_audios_playlists" = "Playlists";
|
||||
|
@ -2385,3 +2388,17 @@
|
|||
"select_doc" = "Attach document";
|
||||
"no_documents" = "No documents found";
|
||||
"go_to_my_documents" = "Go to own documents";
|
||||
|
||||
/* Fave */
|
||||
|
||||
"faves" = "Bookmarks";
|
||||
"faves_empty_tip" = "There will be your liked content.";
|
||||
"faves_posts_empty_tip" = "There will be posts liked by you.";
|
||||
"faves_comments_empty_tip" = "There will be comments liked by you.";
|
||||
"faves_photos_empty_tip" = "There will be photos liked by you.";
|
||||
"faves_videos_empty_tip" = "There will be videos liked by you.";
|
||||
"faves_zero" = "No bookmarks";
|
||||
"faves_one" = "One bookmark";
|
||||
"faves_few" = "$1 bookmarks";
|
||||
"faves_many" = "$1 bookmarks";
|
||||
"faves_other" = "$1 bookmarks";
|
||||
|
|
|
@ -624,6 +624,8 @@
|
|||
"my_feed" = "Мои Новости";
|
||||
"my_feedback" = "Мои Ответы";
|
||||
"my_settings" = "Мои Настройки";
|
||||
"bookmarks" = "Закладки";
|
||||
"bookmarks_tab" = "Избранное";
|
||||
"bug_tracker" = "Баг-трекер";
|
||||
|
||||
"menu_settings" = "Настройки";
|
||||
|
@ -2008,6 +2010,7 @@
|
|||
"s_apps" = "Приложения";
|
||||
"s_posts" = "Записи";
|
||||
"s_comments" = "Комментарии";
|
||||
"s_photos" = "Фотографии";
|
||||
"s_videos" = "Видео";
|
||||
"s_audios" = "Аудио";
|
||||
"s_audios_playlists" = "Плейлисты";
|
||||
|
@ -2280,3 +2283,17 @@
|
|||
"select_doc" = "Выбор документа";
|
||||
"no_documents" = "Документов нет";
|
||||
"go_to_my_documents" = "Перейти к своим документам";
|
||||
|
||||
/* Fave */
|
||||
|
||||
"faves" = "Закладки";
|
||||
"faves_empty_tip" = "Здесь будет отображаться понравившийся Вам контент...";
|
||||
"faves_posts_empty_tip" = "Здесь будут отображаться понравившиеся Вам записи.";
|
||||
"faves_comments_empty_tip" = "Здесь будут отображаться понравившиеся Вам комментарии.";
|
||||
"faves_photos_empty_tip" = "Здесь будут отображаться понравившиеся Вам фотографии.";
|
||||
"faves_videos_empty_tip" = "Здесь будут отображаться понравившиеся Вам видео.";
|
||||
"faves_zero" = "Ни одной закладки"; /* на украинском можно как ни одной вподобайки */
|
||||
"faves_one" = "Одна закладка";
|
||||
"faves_few" = "$1 закладки";
|
||||
"faves_many" = "$1 закладок";
|
||||
"faves_other" = "$1 закладок";
|
||||
|
|
Loading…
Reference in a new issue