mirror of
https://github.com/openvk/openvk
synced 2024-12-23 00:51:03 +03:00
changes to photo viewer + photo/video pages layout
This commit is contained in:
parent
6c2d6f9dd6
commit
890961e63d
16 changed files with 505 additions and 288 deletions
|
@ -134,8 +134,13 @@ class Report extends RowModel
|
|||
|
||||
function getContentName(): string
|
||||
{
|
||||
if (method_exists($this->getContentObject(), "getCanonicalName"))
|
||||
return $this->getContentObject()->getCanonicalName();
|
||||
$content_object = $this->getContentObject();
|
||||
if(!$content_object) {
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
if (method_exists($content_object, "getCanonicalName"))
|
||||
return $content_object->getCanonicalName();
|
||||
|
||||
return $this->getContentType() . " #" . $this->getContentId();
|
||||
}
|
||||
|
|
|
@ -121,9 +121,9 @@ final class InternalAPIPresenter extends OpenVKPresenter
|
|||
{
|
||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo)
|
||||
{
|
||||
$response[] = [
|
||||
"url" => $attachment->getURLBySizeId('normal'),
|
||||
"id" => $attachment->getPrettyId()
|
||||
$response[$attachment->getPrettyId()] = [
|
||||
"url" => $attachment->getURLBySizeId('large'),
|
||||
"id" => $attachment->getPrettyId(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,6 +176,7 @@ final class PhotosPresenter extends OpenVKPresenter
|
|||
$this->template->cCount = $photo->getCommentsCount();
|
||||
$this->template->cPage = (int) ($this->queryParam("p") ?? 1);
|
||||
$this->template->comments = iterator_to_array($photo->getComments($this->template->cPage));
|
||||
$this->template->owner = $photo->getOwner();
|
||||
}
|
||||
|
||||
function renderAbsolutePhoto($id): void
|
||||
|
@ -355,4 +356,26 @@ final class PhotosPresenter extends OpenVKPresenter
|
|||
$this->flash("succ", tr("photo_is_deleted"), tr("photo_is_deleted_desc"));
|
||||
$this->redirect($redirect);
|
||||
}
|
||||
|
||||
function renderLike(int $wall, int $post_id): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
$this->assertNoCSRF();
|
||||
|
||||
$photo = $this->photos->getByOwnerAndVID($wall, $post_id);
|
||||
if(!$photo || $photo->isDeleted() || !$photo->canBeViewedBy($this->user->identity)) $this->notFound();
|
||||
|
||||
if(!is_null($this->user)) {
|
||||
$photo->toggleLike($this->user->identity);
|
||||
}
|
||||
|
||||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$this->returnJson([
|
||||
'success' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->redirect("$_SERVER[HTTP_REFERER]");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
<div class="playIcon"></div>
|
||||
</div>
|
||||
|
||||
<div class="status">
|
||||
<div class="status" draggable='false'>
|
||||
<div class="mediaInfo noOverflow">
|
||||
<div class="info">
|
||||
<strong class="performer">
|
||||
<a draggable='false' href="/search?section=audios&order=listens&only_performers=on&q={$audio->getPerformer()}">{$audio->getPerformer()}</a>
|
||||
<a href="/search?section=audios&order=listens&only_performers=on&q={$audio->getPerformer()}">{$audio->getPerformer()}</a>
|
||||
</strong>
|
||||
—
|
||||
<span class="title {if !empty($audio->getLyrics())}withLyrics{/if}">{$audio->getTitle()}</span>
|
||||
|
|
|
@ -4,76 +4,69 @@
|
|||
|
||||
{block header}
|
||||
{ifset $album}
|
||||
<a href="{$album->getOwner()->getURL()}">
|
||||
{$album->getOwner()->getCanonicalName()}
|
||||
{var $album_owner = $album->getOwner()}
|
||||
<a href="{$album_owner->getURL()}">
|
||||
{$album_owner->getCanonicalName()}
|
||||
</a>
|
||||
{if ($album->getOwner() instanceof openvk\Web\Models\Entities\Club)}
|
||||
» <a href="/albums{$album->getOwner()->getId() * -1}">{_albums}</a>
|
||||
{if ($album_owner instanceof openvk\Web\Models\Entities\Club)}
|
||||
» <a href="/albums{$album_owner->getId() * -1}">{_albums}</a>
|
||||
{else}
|
||||
» <a href="/albums{$album->getOwner()->getId()}">{_albums}</a>
|
||||
» <a href="/albums{$album_owner->getId()}">{_albums}</a>
|
||||
{/if}
|
||||
» <a href="/album{$album->getPrettyId()}">{$album->getName()}</a>
|
||||
{else}
|
||||
<a href="{$photo->getOwner()->getURL()}">{$photo->getOwner()->getCanonicalName()}</a>
|
||||
<a href="{$owner->getURL()}">{$owner->getCanonicalName()}</a>
|
||||
{/ifset}
|
||||
» {_photo}
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<center style="margin-bottom: 8pt;">
|
||||
<img src="{$photo->getURLBySizeId('large')}" style="max-width: 80%; max-height: 60vh;" />
|
||||
</center>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div style="width: 100%; min-height: 100px;" class="ovk-photo-details">
|
||||
<div style="float: left; min-height: 100px; width: 68%;margin-left: 3px;">
|
||||
{include "../components/comments.xml", comments => $comments, count => $cCount, page => $cPage, model => "photos", parent => $photo, custom_id => 999}
|
||||
<div class='media-page-wrapper photo-page-wrapper'>
|
||||
<div class='photo-page-wrapper-photo'>
|
||||
<img src="{$photo->getURLBySizeId('large')}" />
|
||||
</div>
|
||||
<div style="float:right;min-height: 100px;width: 30%;margin-left: 1px;">
|
||||
<div>
|
||||
<h4>{_information}</h4>
|
||||
<span style="color: grey;">{_info_description}:</span>
|
||||
{$photo->getDescription() ?? "(" . tr("none") . ")"}<br/>
|
||||
<span style="color: grey;">{_info_uploaded_by}:</span>
|
||||
<a href="{$photo->getOwner()->getURL()}">{$photo->getOwner()->getFullName()}</a><br/>
|
||||
<span style="color: grey;">{_info_upload_date}:</span>
|
||||
{$photo->getPublicationTime()}
|
||||
|
||||
<div class='ovk-photo-details'>
|
||||
<div class='media-page-wrapper-description'>
|
||||
<p n:if='!empty($photo->getDescription())'>{$photo->getDescription()}</p>
|
||||
<div class='upload_time'>
|
||||
{_info_upload_date}: {$photo->getPublicationTime()}
|
||||
{if isset($thisUser)}
|
||||
|
|
||||
{var $liked = $photo->hasLikeFrom($thisUser)}
|
||||
{var $likesCount = $photo->getLikesCount()}
|
||||
<div class='like_wrap tidy'>
|
||||
<a href="/photo{$photo->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<h4>{_actions}</h4>
|
||||
{if isset($thisUser) && $thisUser->getId() != $photo->getOwner()->getId()}
|
||||
{var canReport = true}
|
||||
{/if}
|
||||
<div n:if="isset($thisUser) && $thisUser->getId() === $photo->getOwner()->getId()">
|
||||
<a href="/photo{$photo->getPrettyId()}/edit" class="profile_link" style="display:block;width:96%;">{_edit}</a>
|
||||
<a id="_photoDelete" href="/photo{$photo->getPrettyId()}/delete" class="profile_link" style="display:block;width:96%;">{_delete}</a>
|
||||
</div>
|
||||
<a href="{$photo->getURL()}" class="profile_link" target="_blank" style="display:block;width:96%;">{_"open_original"}</a>
|
||||
<a n:if="$canReport ?? false" class="profile_link" style="display:block;width:96%;" href="javascript:reportPhoto()">{_report}</a>
|
||||
<script n:if="$canReport ?? false">
|
||||
function reportPhoto() {
|
||||
uReportMsgTxt = tr("going_to_report_photo");
|
||||
uReportMsgTxt += "<br/>"+tr("report_question_text");
|
||||
uReportMsgTxt += "<br/><br/><b>"+tr("report_reason")+"</b>: <input type='text' id='uReportMsgInput' placeholder='" + tr("reason") + "' />"
|
||||
|
||||
MessageBox(tr("report_question"), uReportMsgTxt, [tr("confirm_m"), tr("cancel")], [
|
||||
(function() {
|
||||
res = document.querySelector("#uReportMsgInput").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/report/" + {$photo->getId()} + "?reason=" + res + "&type=photo", true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("reason") === -1)
|
||||
MessageBox(tr("error"), tr("error_sending_report"), ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox(tr("action_successfully"), tr("will_be_watched"), ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
</script>
|
||||
<hr/>
|
||||
|
||||
<div class="media-page-wrapper-details">
|
||||
<div class='media-page-wrapper-comments'>
|
||||
{include "../components/comments.xml", comments => $comments, count => $cCount, page => $cPage, model => "photos", parent => $photo, custom_id => 999}
|
||||
</div>
|
||||
<div class='media-page-wrapper-actions'>
|
||||
<a href="{$owner->getURL()}" class='media-page-author-block'>
|
||||
<img class='cCompactAvatars' src="{$owner->getAvatarURL('miniscule')}">
|
||||
|
||||
<div class='media-page-author-block-name'>
|
||||
<b>{$owner->getCanonicalName()}</b>
|
||||
</div>
|
||||
</a>
|
||||
<div n:if="isset($thisUser) && $thisUser->getId() === $photo->getOwner()->getId()">
|
||||
<a href="/photo{$photo->getPrettyId()}/edit" class="profile_link" style="display:block;width:96%;">{_edit}</a>
|
||||
<a id="_photoDelete" href="/photo{$photo->getPrettyId()}/delete" class="profile_link" style="display:block;width:96%;">{_delete}</a>
|
||||
</div>
|
||||
<a href="{$photo->getURL()}" class="profile_link" target="_blank" style="display:block;width:96%;">{_"open_original"}</a>
|
||||
<a n:if="isset($thisUser) && $thisUser->getId() != $photo->getOwner()->getId()" class="profile_link" style="display:block;width:96%;" href="javascript:reportPhoto({$photo->getId()})">{_report}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
|
|
@ -11,91 +11,108 @@
|
|||
{/block}
|
||||
|
||||
{block content}
|
||||
<center style="margin-bottom: 8pt;">
|
||||
{if $video->getType() === 0}
|
||||
<div class="bsdn" data-name="{$video->getName()}" data-author="{$user->getCanonicalName()}">
|
||||
<video src="{$video->getURL()}"></video>
|
||||
</div>
|
||||
{else}
|
||||
{var $driver = $video->getVideoDriver()}
|
||||
{if !$driver}
|
||||
{_unknown_video}
|
||||
{else}
|
||||
{$driver->getEmbed()|noescape}
|
||||
{/if}
|
||||
{/if}
|
||||
</center>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div style="width: 100%; min-height: 100px;">
|
||||
<div style="float: left; min-height: 100px; width: 68%; margin-right: 2%;" id="comments">
|
||||
{include "../components/comments.xml",
|
||||
comments => $comments,
|
||||
count => $cCount,
|
||||
page => $cPage,
|
||||
model => "videos",
|
||||
parent => $video}
|
||||
</div>
|
||||
<div style="float: left; min-height: 100px; width: 30%; overflow: hidden; overflow-wrap: break-word;">
|
||||
<div>
|
||||
<h4>{_information}</h4>
|
||||
<span style="color: grey;">{_info_name}:</span>
|
||||
{$video->getName()}<br/>
|
||||
<span style="color: grey;">{_info_description}:</span>
|
||||
{$video->getDescription() ?? "(" . tr("none") . ")"}<br/>
|
||||
<span style="color: grey;">{_info_uploaded_by}:</span>
|
||||
<a href="{$user->getURL()}">{$user->getFullName()}</a><br/>
|
||||
<span style="color: grey;">{_info_upload_date}:</span>
|
||||
{$video->getPublicationTime()}
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<div n:if="isset($thisUser) && $thisUser->getId() === $user->getId()">
|
||||
<h4>{_actions}</h4>
|
||||
<a href="/video{$video->getPrettyId()}/edit" class="profile_link" style="display:block;width:96%;">
|
||||
{_edit}
|
||||
</a>
|
||||
<a href="/video{$video->getPrettyId()}/remove" class="profile_link" style="display:block;width:96%;">
|
||||
{_delete}
|
||||
</a>
|
||||
<div class='media-page-wrapper video-page-wrapper'>
|
||||
<div class='video-page-wrapper-video'>
|
||||
{if $video->getType() === 0}
|
||||
<div class="bsdn" data-name="{$video->getName()}" data-author="{$user->getCanonicalName()}">
|
||||
<video src="{$video->getURL()}"></video>
|
||||
</div>
|
||||
<a href="/video{$video->getPrettyId()}" class="profile_link" id="videoOpen" data-id="{$video->getId()}" style="display:block;width:96%;">
|
||||
{_watch_in_window}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{if isset($thisUser)}
|
||||
{if $thisUser->getId() != $video->getOwner()->getId()}
|
||||
{var canReport = true}
|
||||
{else}
|
||||
{var $driver = $video->getVideoDriver()}
|
||||
{if !$driver}
|
||||
{_unknown_video}
|
||||
{else}
|
||||
{$driver->getEmbed()|noescape}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<a n:if="$canReport ?? false" class="profile_link" style="display:block;width:96%;" href="javascript:reportVideo()">{_report}</a>
|
||||
|
||||
<script n:if="$canReport ?? false">
|
||||
function reportVideo() {
|
||||
uReportMsgTxt = tr("going_to_report_video");
|
||||
uReportMsgTxt += "<br/>"+tr("report_question_text");
|
||||
uReportMsgTxt += "<br/><br/><b>"+tr("report_reason")+"</b>: <input type='text' id='uReportMsgInput' placeholder='" + tr("reason") + "' />"
|
||||
|
||||
MessageBox(tr("report_question"), uReportMsgTxt, [tr("confirm_m"), tr("cancel")], [
|
||||
(function() {
|
||||
res = document.querySelector("#uReportMsgInput").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/report/" + {$video->getId()} + "?reason=" + res + "&type=video", true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("reason") === -1)
|
||||
MessageBox(tr("error"), tr("error_sending_report"), ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox(tr("action_successfully"), tr("will_be_watched"), ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div class='ovk-vid-details'>
|
||||
<div class='media-page-wrapper-description'>
|
||||
<p><b>{$video->getName()}</b></p>
|
||||
<p n:if='!empty($video->getDescription())'>{$video->getDescription()}</p>
|
||||
<div class='upload_time'>
|
||||
{_info_upload_date}: {$video->getPublicationTime()}
|
||||
{if isset($thisUser)}
|
||||
|
|
||||
{var $liked = $video->hasLikeFrom($thisUser)}
|
||||
{var $likesCount = $video->getLikesCount()}
|
||||
<div class='like_wrap tidy'>
|
||||
<a href="/video{$video->getPrettyId()}/like?hash={rawurlencode($csrfToken)}" class="post-like-button" data-liked="{(int) $liked}" data-likes="{$likesCount}">
|
||||
<div class="heart" id="{if $liked}liked{/if}"></div>
|
||||
<span class="likeCnt">{if $likesCount > 0}{$likesCount}{/if}</span>
|
||||
</a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="media-page-wrapper-details">
|
||||
<div class='media-page-wrapper-comments' id="comments">
|
||||
{include "../components/comments.xml",
|
||||
comments => $comments,
|
||||
count => $cCount,
|
||||
page => $cPage,
|
||||
model => "videos",
|
||||
parent => $video}
|
||||
</div>
|
||||
<div class='media-page-wrapper-actions'>
|
||||
<a href="{$user->getURL()}" class='media-page-author-block'>
|
||||
<img class='cCompactAvatars' src="{$user->getAvatarURL('miniscule')}">
|
||||
|
||||
<div class='media-page-author-block-name'>
|
||||
<b>{$user->getCanonicalName()}</b>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div>
|
||||
<div n:if="isset($thisUser) && $thisUser->getId() === $user->getId()">
|
||||
<a href="/video{$video->getPrettyId()}/edit" class="profile_link" style="display:block;width:96%;">
|
||||
{_edit}
|
||||
</a>
|
||||
<a id='_videoDelete' href="/video{$video->getPrettyId()}/remove" class="profile_link" style="display:block;width:96%;">
|
||||
{_delete}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if isset($thisUser)}
|
||||
{if $thisUser->getId() != $video->getOwner()->getId()}
|
||||
{var canReport = true}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<a n:if="$canReport ?? false" class="profile_link" style="display:block;width:96%;" href="javascript:reportVideo()">{_report}</a>
|
||||
|
||||
<script n:if="$canReport ?? false">
|
||||
function reportVideo() {
|
||||
uReportMsgTxt = tr("going_to_report_video");
|
||||
uReportMsgTxt += "<br/>"+tr("report_question_text");
|
||||
uReportMsgTxt += "<br/><br/><b>"+tr("report_reason")+"</b>: <input type='text' id='uReportMsgInput' placeholder='" + tr("reason") + "' />"
|
||||
|
||||
MessageBox(tr("report_question"), uReportMsgTxt, [tr("confirm_m"), tr("cancel")], [
|
||||
(function() {
|
||||
res = document.querySelector("#uReportMsgInput").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/report/" + {$video->getId()} + "?reason=" + res + "&type=video", true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("reason") === -1)
|
||||
MessageBox(tr("error"), tr("error_sending_report"), ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox(tr("action_successfully"), tr("will_be_watched"), ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
{/block}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{if $attachment instanceof \openvk\Web\Models\Entities\Photo}
|
||||
{if !$attachment->isDeleted()}
|
||||
{var $link = "/photo" . ($attachment->isAnonymous() ? ("s/" . base_convert((string) $attachment->getId(), 10, 32)) : $attachment->getPrettyId())}
|
||||
<a href="{$link}" onclick="OpenMiniature(event, {$attachment->getURLBySizeId('normal')}, {$parent->getPrettyId()}, {$attachment->getPrettyId()}, {$parentType})">
|
||||
<a href="{$link}" onclick="OpenMiniature(event, {$attachment->getURLBySizeId('larger')}, {$parent->getPrettyId()}, {$attachment->getPrettyId()}, {$parentType})">
|
||||
<img class="media media_makima" src="{$attachment->getURLBySizeId('normal')}" alt="{$attachment->getDescription()}" loading=lazy />
|
||||
</a>
|
||||
{else}
|
||||
|
|
|
@ -171,6 +171,8 @@ routes:
|
|||
handler: "Photos->uploadPhoto"
|
||||
- url: "/photo{num}_{num}"
|
||||
handler: "Photos->photo"
|
||||
- url: "/photo{num}_{num}/like"
|
||||
handler: "Photos->like"
|
||||
- url: "/photos/thumbnails/{num}_{text}.jpeg"
|
||||
handler: "Photos->thumbnail"
|
||||
- url: "/photos/{text}"
|
||||
|
|
|
@ -783,6 +783,7 @@
|
|||
|
||||
.addToPlaylist {
|
||||
width: 22%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#_addAudioAdditional {
|
||||
|
|
|
@ -13,7 +13,7 @@ body {
|
|||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
body, .ovk-fullscreen-dimmer {
|
||||
body, .ovk-fullscreen-dimmer, .ovk-photo-view-dimmer {
|
||||
scrollbar-gutter: stable both-edges;
|
||||
}
|
||||
|
||||
|
@ -1574,6 +1574,15 @@ body.scrolled .toTop:hover {
|
|||
float: right;
|
||||
}
|
||||
|
||||
.like_wrap.tidy {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.like_wrap.tidy .post-like-button {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.heart {
|
||||
background: url('/assets/packages/static/openvk/img/like.gif') no-repeat 1px 0;
|
||||
height: 10px;
|
||||
|
@ -1583,12 +1592,22 @@ body.scrolled .toTop:hover {
|
|||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.like_wrap.tidy .heart {
|
||||
float: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.likeCnt {
|
||||
font-size: 10px;
|
||||
margin-right: 3px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.like_wrap.tidy .likeCnt {
|
||||
float: none;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.heart:hover {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
@ -2439,6 +2458,7 @@ a.poll-retract-vote {
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
min-height: 63px;
|
||||
}
|
||||
|
||||
.post-horizontal .upload-item .play-button, .compact_video .play-button {
|
||||
|
@ -2551,21 +2571,33 @@ a.poll-retract-vote {
|
|||
position: relative;
|
||||
z-index: 999;
|
||||
background: #fff;
|
||||
width: 610px;
|
||||
padding: 20px;
|
||||
min-width: 600px;
|
||||
width: fit-content;
|
||||
padding: 25px;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 10px;
|
||||
box-shadow: 0px 0px 3px 1px #222;
|
||||
margin: 15px auto 0 auto;
|
||||
margin: 10px auto 0 auto;
|
||||
}
|
||||
|
||||
.ovk-photo-details {
|
||||
overflow: auto;
|
||||
.ovk-photo-view .photo_viewer_wrapper {
|
||||
position: relative;
|
||||
height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ovk-photo-view #ovk-photo-img {
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.photo_com_title {
|
||||
font-weight: bold;
|
||||
padding-bottom: 20px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.photo_com_title div {
|
||||
|
@ -2577,7 +2609,6 @@ a.poll-retract-vote {
|
|||
left: 0;
|
||||
width: 35%;
|
||||
height: 100%;
|
||||
max-height: 60vh;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -2586,11 +2617,25 @@ a.poll-retract-vote {
|
|||
right: 0;
|
||||
width: 35%;
|
||||
height: 100%;
|
||||
max-height: 60vh;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ovk-photo-view .media-page-wrapper-details {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.ovk-photo-view .media-page-wrapper-comments {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.ovk-photo-view .ovk-photo-details {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.client_app > img {
|
||||
top: 3px;
|
||||
position: relative;
|
||||
|
@ -3535,3 +3580,72 @@ hr {
|
|||
color: white;
|
||||
}
|
||||
|
||||
.media-page-wrapper .photo-page-wrapper-photo {
|
||||
margin-bottom: 8pt;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.media-page-wrapper .video-page-wrapper-video {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.media-page-wrapper .photo-page-wrapper-photo img {
|
||||
max-width: 85%;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
.media-page-wrapper-details {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.media-page-wrapper-comments {
|
||||
min-height: 100px;
|
||||
width: 68%;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.media-page-wrapper-actions {
|
||||
min-height: 100px;
|
||||
width: 30%;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.media-page-wrapper-description p {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.media-page-wrapper-description .upload_time {
|
||||
color: gray;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.media-page-author-block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.media-page-author-block img {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.media-page-author-block .media-page-author-block-name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.media-page-author-block .media-page-author-block-name b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.media-page-author-block .media-page-author-block-name span {
|
||||
text-transform: lowercase;
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
|
@ -49,7 +49,7 @@ window.OVKAPI = new class {
|
|||
if(json_response.response) {
|
||||
return json_response.response
|
||||
} else {
|
||||
throw new Exception(json_response.error_msg)
|
||||
throw new Error(json_response.error_msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,175 +85,207 @@ u(document).on("input", "textarea", function(e) {
|
|||
// textArea.style.height = (newHeight > originalHeight ? (newHeight + boost) : originalHeight) + "px";
|
||||
});
|
||||
|
||||
function OpenMiniature(e, photo, post, photo_id, type = "post") {
|
||||
async function OpenMiniature(e, photo, post, photo_id, type = "post") {
|
||||
/*
|
||||
костыли но смешные однако
|
||||
*/
|
||||
e.preventDefault();
|
||||
|
||||
if(u(".ovk-photo-view").length > 0) u(".ovk-photo-view-dimmer").remove();
|
||||
|
||||
// Значения для переключения фоток
|
||||
|
||||
const albums_per_page = 20
|
||||
let json;
|
||||
let offset = type == 'album' ? (Number((new URL(location.href)).searchParams.get('p') ?? 1) - 1) * albums_per_page : 0
|
||||
let shown_offset = 0
|
||||
|
||||
let imagesCount = 0;
|
||||
let imagesIndex = 0;
|
||||
let currentImageid = '0_0';
|
||||
|
||||
let tempDetailsSection = [];
|
||||
|
||||
let dialog = u(
|
||||
`<div class="ovk-photo-view-dimmer">
|
||||
<div class="ovk-photo-view">
|
||||
<div class="photo_com_title">
|
||||
<text id="photo_com_title_photos">
|
||||
const photo_viewer = new CMessageBox({
|
||||
title: '',
|
||||
custom_template: u(`
|
||||
<div class="ovk-photo-view-dimmer">
|
||||
<div class="ovk-photo-view">
|
||||
<div class="photo_com_title">
|
||||
<text id="photo_com_title_photos">
|
||||
<img src="/assets/packages/static/openvk/img/loading_mini.gif">
|
||||
</text>
|
||||
<div>
|
||||
<a id="ovk-photo-close">${tr("close")}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class='photo_viewer_wrapper'>
|
||||
<div class="ovk-photo-slide-left"></div>
|
||||
<div class="ovk-photo-slide-right"></div>
|
||||
<img src="${photo}" id="ovk-photo-img">
|
||||
</div>
|
||||
<div class="ovk-photo-details">
|
||||
<img src="/assets/packages/static/openvk/img/loading_mini.gif">
|
||||
</text>
|
||||
<div>
|
||||
<a id="ovk-photo-close">${tr("close")}</a>
|
||||
</div>
|
||||
</div>
|
||||
<center style="margin-bottom: 8pt; position: relative;">
|
||||
<div class="ovk-photo-slide-left"></div>
|
||||
<div class="ovk-photo-slide-right"></div>
|
||||
<img src="${photo}" style="max-width: 100%; max-height: 60vh; user-select:none;" id="ovk-photo-img">
|
||||
</center>
|
||||
<div class="ovk-photo-details">
|
||||
<img src="/assets/packages/static/openvk/img/loading_mini.gif">
|
||||
</div>
|
||||
</div>
|
||||
</div>`);
|
||||
u("body").addClass("dimmed").append(dialog);
|
||||
document.querySelector("html").style.overflowY = "hidden"
|
||||
|
||||
let button = u("#ovk-photo-close");
|
||||
</div>`)
|
||||
})
|
||||
|
||||
button.on("click", function(e) {
|
||||
let __closeDialog = () => {
|
||||
u("body").removeClass("dimmed");
|
||||
u(".ovk-photo-view-dimmer").remove();
|
||||
document.querySelector("html").style.overflowY = "scroll"
|
||||
};
|
||||
|
||||
__closeDialog();
|
||||
photo_viewer.getNode().find("#ovk-photo-close").on("click", function(e) {
|
||||
photo_viewer.close()
|
||||
});
|
||||
|
||||
function __reloadTitleBar() {
|
||||
u("#photo_com_title_photos").last().innerHTML = imagesCount > 1 ? tr("photo_x_from_y", imagesIndex, imagesCount) : tr("photo");
|
||||
function __getIndex(photo_id = null) {
|
||||
return Object.keys(json.body).findIndex(item => item == (photo_id ?? currentImageid)) + 1
|
||||
}
|
||||
|
||||
function __loadDetails(photo_id, index) {
|
||||
if(tempDetailsSection[index] == null) {
|
||||
u(".ovk-photo-details").last().innerHTML = '<img src="/assets/packages/static/openvk/img/loading_mini.gif">';
|
||||
ky("/photo" + photo_id, {
|
||||
hooks: {
|
||||
afterResponse: [
|
||||
async (_request, _options, response) => {
|
||||
let parser = new DOMParser();
|
||||
let body = parser.parseFromString(await response.text(), "text/html");
|
||||
function __getByIndex(id) {
|
||||
const ids = Object.keys(json.body)
|
||||
const _id = ids[id - 1]
|
||||
|
||||
let element = u(body.getElementsByClassName("ovk-photo-details")).last();
|
||||
return json.body[_id]
|
||||
}
|
||||
|
||||
tempDetailsSection[index] = element.innerHTML;
|
||||
function __reloadTitleBar() {
|
||||
photo_viewer.getNode().find("#photo_com_title_photos").last().innerHTML = imagesCount > 1 ? tr("photo_x_from_y", shown_offset, imagesCount) : tr("photo");
|
||||
}
|
||||
|
||||
if(index == imagesIndex) {
|
||||
u(".ovk-photo-details").last().innerHTML = element.innerHTML ?? '';
|
||||
}
|
||||
async function __loadDetails(photo_id) {
|
||||
if(json.body[photo_id].cached == null) {
|
||||
photo_viewer.getNode().find(".ovk-photo-details").last().innerHTML = '<img src="/assets/packages/static/openvk/img/loading_mini.gif">';
|
||||
const photo_url = `/photo${photo_id}`
|
||||
const photo_page = await fetch(photo_url)
|
||||
const photo_text = await photo_page.text()
|
||||
const parser = new DOMParser
|
||||
const body = parser.parseFromString(photo_text, "text/html")
|
||||
const details = body.querySelector('.ovk-photo-details')
|
||||
json.body[photo_id].cached = details.innerHTML ?? ''
|
||||
if(photo_id == currentImageid) {
|
||||
photo_viewer.getNode().find(".ovk-photo-details").last().innerHTML = details.innerHTML ?? '';
|
||||
}
|
||||
|
||||
document.querySelectorAll(".ovk-photo-details .bsdn").forEach(bsdnInitElement)
|
||||
document.querySelectorAll(".ovk-photo-details script").forEach(scr => {
|
||||
// stolen from #953
|
||||
let newScr = document.createElement('script')
|
||||
|
||||
if(scr.src) {
|
||||
newScr.src = scr.src
|
||||
} else {
|
||||
newScr.textContent = scr.textContent
|
||||
}
|
||||
|
||||
document.querySelector(".ovk-photo-details").appendChild(newScr);
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
photo_viewer.getNode().find(".ovk-photo-details .bsdn").nodes.forEach(bsdnInitElement)
|
||||
} else {
|
||||
u(".ovk-photo-details").last().innerHTML = tempDetailsSection[index];
|
||||
photo_viewer.getNode().find(".ovk-photo-details").last().innerHTML = json.body[photo_id].cached
|
||||
}
|
||||
}
|
||||
|
||||
function __slidePhoto(direction) {
|
||||
async function __slidePhoto(direction) {
|
||||
/* direction = 1 - right
|
||||
direction = 0 - left */
|
||||
if(json == undefined) {
|
||||
console.log("Да подожди ты. Куда торопишься?");
|
||||
} else {
|
||||
if(imagesIndex >= imagesCount && direction == 1) {
|
||||
imagesIndex = 1;
|
||||
} else if(imagesIndex <= 1 && direction == 0) {
|
||||
imagesIndex = imagesCount;
|
||||
let current_index = __getIndex()
|
||||
if(current_index >= imagesCount && direction == 1) {
|
||||
shown_offset = 1
|
||||
current_index = 1
|
||||
} else if(current_index <= 1 && direction == 0) {
|
||||
shown_offset += imagesCount - 1
|
||||
current_index = imagesCount
|
||||
} else if(direction == 1) {
|
||||
imagesIndex++;
|
||||
shown_offset += 1
|
||||
current_index += 1
|
||||
} else if(direction == 0) {
|
||||
imagesIndex--;
|
||||
shown_offset -= 1
|
||||
current_index -= 1
|
||||
}
|
||||
|
||||
let photoURL = json.body[imagesIndex - 1].url;
|
||||
currentImageid = __getByIndex(current_index)
|
||||
if(!currentImageid) {
|
||||
if(type == 'album') {
|
||||
if(direction == 1) {
|
||||
offset += albums_per_page
|
||||
} else {
|
||||
offset -= albums_per_page
|
||||
}
|
||||
|
||||
await __loadContext(type, post, true, direction == 0)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
currentImageid = currentImageid.id
|
||||
let photoURL = json.body[currentImageid].url;
|
||||
|
||||
u("#ovk-photo-img").last().src = photoURL;
|
||||
photo_viewer.getNode().find("#ovk-photo-img").last().src = ''
|
||||
photo_viewer.getNode().find("#ovk-photo-img").last().src = photoURL;
|
||||
__reloadTitleBar();
|
||||
__loadDetails(json.body[imagesIndex - 1].id, imagesIndex);
|
||||
__loadDetails(json.body[currentImageid].id);
|
||||
}
|
||||
}
|
||||
|
||||
let slideLeft = u(".ovk-photo-slide-left");
|
||||
|
||||
slideLeft.on("click", (e) => {
|
||||
__slidePhoto(0);
|
||||
});
|
||||
|
||||
let slideRight = u(".ovk-photo-slide-right");
|
||||
|
||||
slideRight.on("click", (e) => {
|
||||
__slidePhoto(1);
|
||||
});
|
||||
|
||||
let data = new FormData()
|
||||
data.append('parentType', type);
|
||||
async function __loadContext(type, id, ref = false, inverse = false) {
|
||||
if(type == 'post' || type == 'comment') {
|
||||
const form_data = new FormData()
|
||||
form_data.append('parentType', type);
|
||||
|
||||
if(type) {
|
||||
ky.post("/iapi/getPhotosFromPost/" + (type == "post" ? post : "1_"+post), {
|
||||
hooks: {
|
||||
afterResponse: [
|
||||
async (_request, _options, response) => {
|
||||
json = await response.json();
|
||||
|
||||
imagesCount = json.body.length;
|
||||
imagesIndex = 0;
|
||||
// Это всё придётся правда на 1 прибавлять
|
||||
|
||||
json.body.every(element => {
|
||||
imagesIndex++;
|
||||
if(element.id == photo_id) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
__reloadTitleBar();
|
||||
__loadDetails(json.body[imagesIndex - 1].id, imagesIndex); }
|
||||
]
|
||||
},
|
||||
body: data
|
||||
});
|
||||
} else {
|
||||
imagesCount = 1
|
||||
__reloadTitleBar()
|
||||
__loadDetails(photo_id, imagesIndex)
|
||||
const endpoint_url = `/iapi/getPhotosFromPost/${type == "post" ? id : "1_"+id}`
|
||||
const fetcher = await fetch(endpoint_url, {
|
||||
method: 'POST',
|
||||
body: form_data,
|
||||
})
|
||||
json = await fetcher.json()
|
||||
imagesCount = Object.entries(json.body).length
|
||||
} else {
|
||||
const params = {
|
||||
'offset': offset,
|
||||
'count': albums_per_page,
|
||||
'owner_id': id.split('_')[0],
|
||||
'album_id': id.split('_')[1],
|
||||
'photo_sizes': 1
|
||||
}
|
||||
|
||||
const result = await window.OVKAPI.call('photos.get', params)
|
||||
const converted_items = {}
|
||||
|
||||
result.items.forEach(item => {
|
||||
const id = item.owner_id + '_' + item.id
|
||||
converted_items[id] = {
|
||||
'url': item.src_xbig,
|
||||
'id': id,
|
||||
}
|
||||
})
|
||||
imagesCount = result.count
|
||||
|
||||
if(!json)
|
||||
json = {'body': []}
|
||||
|
||||
if(!inverse) {
|
||||
json.body = Object.assign(converted_items, json.body)
|
||||
} else {
|
||||
json.body = Object.assign(json.body, converted_items)
|
||||
}
|
||||
}
|
||||
|
||||
currentImageid = photo_id
|
||||
}
|
||||
|
||||
return u(".ovk-photo-view-dimmer");
|
||||
photo_viewer.getNode().find(".ovk-photo-slide-left").on("click", (e) => {
|
||||
__slidePhoto(0);
|
||||
})
|
||||
photo_viewer.getNode().find(".ovk-photo-slide-right").on("click", (e) => {
|
||||
__slidePhoto(1);
|
||||
})
|
||||
|
||||
if(!type) {
|
||||
imagesCount = 1
|
||||
json = {
|
||||
'body': {}
|
||||
}
|
||||
|
||||
json.body[photo_id] = {
|
||||
'id': photo_id,
|
||||
'url': photo
|
||||
}
|
||||
currentImageid = photo_id
|
||||
|
||||
__reloadTitleBar()
|
||||
__loadDetails(photo_id)
|
||||
} else {
|
||||
await __loadContext(type, post)
|
||||
shown_offset = offset + __getIndex()
|
||||
|
||||
__reloadTitleBar();
|
||||
__loadDetails(json.body[currentImageid].id);
|
||||
}
|
||||
|
||||
return photo_viewer.getNode()
|
||||
}
|
||||
|
||||
u("#write > form").on("keydown", function(event) {
|
||||
|
@ -261,6 +293,28 @@ u("#write > form").on("keydown", function(event) {
|
|||
this.submit();
|
||||
});
|
||||
|
||||
function reportPhoto(photo_id) {
|
||||
uReportMsgTxt = tr("going_to_report_photo");
|
||||
uReportMsgTxt += "<br/>"+tr("report_question_text");
|
||||
uReportMsgTxt += "<br/><br/><b>"+tr("report_reason")+"</b>: <input type='text' id='uReportMsgInput' placeholder='" + tr("reason") + "' />"
|
||||
|
||||
MessageBox(tr("report_question"), uReportMsgTxt, [tr("confirm_m"), tr("cancel")], [
|
||||
(function() {
|
||||
res = document.querySelector("#uReportMsgInput").value;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "/report/" + photo_id + "?reason=" + res + "&type=photo", true);
|
||||
xhr.onload = (function() {
|
||||
if(xhr.responseText.indexOf("reason") === -1)
|
||||
MessageBox(tr("error"), tr("error_sending_report"), ["OK"], [Function.noop]);
|
||||
else
|
||||
MessageBox(tr("action_successfully"), tr("will_be_watched"), ["OK"], [Function.noop]);
|
||||
});
|
||||
xhr.send(null);
|
||||
}),
|
||||
Function.noop
|
||||
]);
|
||||
}
|
||||
|
||||
var tooltipClientTemplate = Handlebars.compile(`
|
||||
<table>
|
||||
<tr>
|
||||
|
|
|
@ -9,6 +9,7 @@ class CMessageBox {
|
|||
const close_on_buttons = options.close_on_buttons ?? true
|
||||
const unique_name = options.unique_name ?? null
|
||||
const warn_on_exit = options.warn_on_exit ?? false
|
||||
const custom_template = options.custom_template ?? null
|
||||
if(unique_name && window.messagebox_stack.find(item => item.unique_name == unique_name) != null) {
|
||||
return
|
||||
}
|
||||
|
@ -20,7 +21,14 @@ class CMessageBox {
|
|||
this.unique_name = unique_name
|
||||
this.warn_on_exit = warn_on_exit
|
||||
|
||||
u('body').addClass('dimmed').append(this.__getTemplate())
|
||||
if(!custom_template) {
|
||||
u('body').addClass('dimmed').append(this.__getTemplate())
|
||||
} else {
|
||||
custom_template.addClass('ovk-msg-all')
|
||||
custom_template.attr('data-id', this.id)
|
||||
u('body').addClass('dimmed').append(custom_template)
|
||||
}
|
||||
|
||||
u('html').attr('style', 'overflow-y:hidden')
|
||||
|
||||
buttons.forEach((text, callback) => {
|
||||
|
@ -40,7 +48,7 @@ class CMessageBox {
|
|||
|
||||
__getTemplate() {
|
||||
return u(
|
||||
`<div class="ovk-diag-cont" data-id="${this.id}">
|
||||
`<div class="ovk-diag-cont ovk-msg-all" data-id="${this.id}">
|
||||
<div class="ovk-diag">
|
||||
<div class="ovk-diag-head">${this.title}</div>
|
||||
<div class="ovk-diag-body">${this.body}</div>
|
||||
|
@ -50,7 +58,7 @@ class CMessageBox {
|
|||
}
|
||||
|
||||
getNode() {
|
||||
return u(`.ovk-diag-cont[data-id='${this.id}']`)
|
||||
return u(`.ovk-msg-all[data-id='${this.id}']`)
|
||||
}
|
||||
|
||||
async __showCloseConfirmationDialog() {
|
||||
|
@ -73,8 +81,8 @@ class CMessageBox {
|
|||
}
|
||||
|
||||
__exitDialog() {
|
||||
u(`.ovk-diag-cont[data-id='${this.id}']`).remove()
|
||||
if(u('.ovk-diag-cont').length < 1) {
|
||||
this.getNode().remove()
|
||||
if(u('.ovk-msg-all').length < 1) {
|
||||
u('body').removeClass('dimmed')
|
||||
u('html').attr('style', 'overflow-y:scroll')
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ function parseAjaxResponse(responseString) {
|
|||
|
||||
document.addEventListener("DOMContentLoaded", function() { //BEGIN
|
||||
|
||||
$(document).on("click", "#_photoDelete", function(e) {
|
||||
$(document).on("click", "#_photoDelete, #_videoDelete", function(e) {
|
||||
var formHtml = "<form id='tmpPhDelF' action='" + u(this).attr("href") + "' >";
|
||||
formHtml += "<input type='hidden' name='hash' value='" + u("meta[name=csrf]").attr("value") + "' />";
|
||||
formHtml += "</form>";
|
||||
|
|
Loading…
Reference in a new issue