diff --git a/VKAPI/Handlers/Video.php b/VKAPI/Handlers/Video.php
index 975ce1c3..bc962b70 100755
--- a/VKAPI/Handlers/Video.php
+++ b/VKAPI/Handlers/Video.php
@@ -11,7 +11,7 @@ use openvk\Web\Models\Repositories\Comments as CommentsRepo;
final class Video extends VKAPIRequestHandler
{
- function get(int $owner_id, string $videos = "", int $offset = 0, int $count = 30, int $extended = 0): object
+ function get(int $owner_id, string $videos = "", string $fields = "", int $offset = 0, int $count = 30, int $extended = 0): object
{
$this->requireUser();
@@ -46,12 +46,46 @@ final class Video extends VKAPIRequestHandler
if(!$user->getPrivacyPermission('videos.read', $this->getUser()))
$this->fail(21, "This user chose to hide his videos.");
- $videos = (new VideosRepo)->getByUser($user, $offset + 1, $count);
+ $videos = (new VideosRepo)->getByUserLimit($user, $offset, $count);
$videosCount = (new VideosRepo)->getUserVideosCount($user);
$items = [];
- foreach ($videos as $video) {
- $items[] = $video->getApiStructure($this->getUser());
+ $profiles = [];
+ $groups = [];
+ foreach($videos as $video) {
+ $video = $video->getApiStructure($this->getUser())->video;
+ $items[] = $video;
+ if($video['owner_id']) {
+ if($video['owner_id'] > 0)
+ $profiles[] = $video['owner_id'];
+ else
+ $groups[] = abs($video['owner_id']);
+ }
+ }
+
+ if($extended == 1) {
+ $profiles = array_unique($profiles);
+ $groups = array_unique($groups);
+
+ $profilesFormatted = [];
+ $groupsFormatted = [];
+
+ foreach($profiles as $prof) {
+ $profile = (new UsersRepo)->get($prof);
+ $profilesFormatted[] = $profile->toVkApiStruct($this->getUser(), $fields);
+ }
+
+ foreach($groups as $gr) {
+ $group = (new ClubsRepo)->get($gr);
+ $groupsFormatted[] = $group->toVkApiStruct($this->getUser(), $fields);
+ }
+
+ return (object) [
+ "count" => $videosCount,
+ "items" => $items,
+ "profiles" => $profilesFormatted,
+ "groups" => $groupsFormatted,
+ ];
}
return (object) [
diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php
index f4a83d8c..c2c73293 100644
--- a/VKAPI/Handlers/Wall.php
+++ b/VKAPI/Handlers/Wall.php
@@ -473,7 +473,7 @@ final class Wall extends VKAPIRequestHandler
];
}
- function post(string $owner_id, string $message = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0): object
+ function post(string $owner_id, string $message = "", string $copyright = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0): object
{
$this->requireUser();
$this->willExecuteWriteAction();
@@ -551,7 +551,17 @@ final class Wall extends VKAPIRequestHandler
if($signed == 1)
$flags |= 0b01000000;
- if(empty($message) && empty($attachments))
+ $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'poll', 'audio']);
+ $final_attachments = [];
+ $should_be_suggested = $owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2;
+ foreach($parsed_attachments as $attachment) {
+ if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) &&
+ !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) {
+ $final_attachments[] = $attachment;
+ }
+ }
+
+ if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1)))
$this->fail(100, "Required parameter 'message' missing.");
try {
@@ -569,7 +579,7 @@ final class Wall extends VKAPIRequestHandler
} catch(\Throwable) {}
}
- if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2)
+ if($should_be_suggested)
$post->setSuggested(1);
$post->save();
@@ -577,90 +587,14 @@ final class Wall extends VKAPIRequestHandler
$this->fail(100, "One of the parameters specified was missing or invalid");
}
- # TODO use parseAttachments
- if(!empty($attachments)) {
- $attachmentsArr = explode(",", $attachments);
- # Аттачи такого вида: [тип][id владельца]_[id вложения]
- # Пример: photo1_1
-
- if(sizeof($attachmentsArr) > 10)
- $this->fail(50, "Too many attachments");
-
- preg_match_all("/poll/m", $attachments, $matches, PREG_SET_ORDER, 0);
- if(sizeof($matches) > 1)
- $this->fail(85, "Too many polls");
-
- foreach($attachmentsArr as $attac) {
- $attachmentType = NULL;
-
- if(str_contains($attac, "photo"))
- $attachmentType = "photo";
- elseif(str_contains($attac, "video"))
- $attachmentType = "video";
- elseif(str_contains($attac, "note"))
- $attachmentType = "note";
- elseif(str_contains($attac, "poll"))
- $attachmentType = "poll";
- elseif(str_contains($attac, "audio"))
- $attachmentType = "audio";
-
- else
- $this->fail(205, "Unknown attachment type");
-
- $attachment = str_replace($attachmentType, "", $attac);
-
- $attachmentOwner = (int)explode("_", $attachment)[0];
- $attachmentId = (int)end(explode("_", $attachment));
-
- $attacc = NULL;
-
- if($attachmentType == "photo") {
- $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Invalid photo");
- if(!$attacc->getOwner()->getPrivacyPermission('photos.read', $this->getUser()))
- $this->fail(43, "Access to photo denied");
-
- $post->attach($attacc);
- } elseif($attachmentType == "video") {
- $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Video does not exists");
- if(!$attacc->getOwner()->getPrivacyPermission('videos.read', $this->getUser()))
- $this->fail(43, "Access to video denied");
-
- $post->attach($attacc);
- } elseif($attachmentType == "note") {
- $attacc = (new NotesRepo)->getNoteById($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Note does not exist");
- if(!$attacc->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
- $this->fail(11, "Access to note denied");
-
- $post->attach($attacc);
- } elseif($attachmentType == "poll") {
- $attacc = (new PollsRepo)->get($attachmentId);
-
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Poll does not exist");
- if($attacc->getOwner()->getId() != $this->getUser()->getId())
- $this->fail(43, "You do not have access to this poll");
-
- $post->attach($attacc);
- } elseif($attachmentType == "audio") {
- $attacc = (new AudiosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Audio does not exist");
-
- $post->attach($attacc);
- }
- }
+ foreach($final_attachments as $attachment) {
+ $post->attach($attachment);
}
if($wall > 0 && $wall !== $this->user->identity->getId())
(new WallPostNotification($wallOwner, $post, $this->user->identity))->emit();
- if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2) {
+ if($should_be_suggested) {
return (object)["post_id" => "on_view"];
}
@@ -675,6 +609,15 @@ final class Wall extends VKAPIRequestHandler
if(preg_match('/wall((?:-?)[0-9]+)_([0-9]+)/', $object, $postArray) == 0)
$this->fail(100, "One of the parameters specified was missing or invalid: object is incorrect");
+ $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']);
+ $final_attachments = [];
+ foreach($parsed_attachments as $attachment) {
+ if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) &&
+ !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) {
+ $final_attachments[] = $attachment;
+ }
+ }
+
$post = (new PostsRepo)->getPostById((int) $postArray[1], (int) $postArray[2]);
if(!$post || $post->isDeleted()) $this->fail(100, "One of the parameters specified was missing or invalid");
@@ -710,12 +653,8 @@ final class Wall extends VKAPIRequestHandler
$nPost->save();
$nPost->attach($post);
- $attachments_arr = parseAttachments($attachments, ['photo', 'video', 'audio']);
- foreach($attachments_arr as $attachment) {
- if(!$attachment || $attachment->isDeleted() || !$attachment->canBeViewedBy($this->getUser())) {
- continue;
- }
+ foreach($parsed_attachments as $attachment) {
$nPost->attach($attachment);
}
@@ -905,7 +844,16 @@ final class Wall extends VKAPIRequestHandler
if($post->getTargetWall() < 0)
$club = (new ClubsRepo)->get(abs($post->getTargetWall()));
- if(empty($message) && empty($attachments)) {
+ $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']);
+ $final_attachments = [];
+ foreach($parsed_attachments as $attachment) {
+ if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) &&
+ !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) {
+ $final_attachments[] = $attachment;
+ }
+ }
+
+ if((empty($message) && (empty($attachments) || sizeof($final_attachments) < 1))) {
$this->fail(100, "Required parameter 'message' missing.");
}
@@ -926,55 +874,8 @@ final class Wall extends VKAPIRequestHandler
$this->fail(1, "ошибка про то что коммент большой слишком");
}
- if(!empty($attachments)) {
- $attachmentsArr = explode(",", $attachments);
-
- if(sizeof($attachmentsArr) > 10)
- $this->fail(50, "Error: too many attachments");
-
- foreach($attachmentsArr as $attac) {
- $attachmentType = NULL;
-
- if(str_contains($attac, "photo"))
- $attachmentType = "photo";
- elseif(str_contains($attac, "video"))
- $attachmentType = "video";
- elseif(str_contains($attac, "audio"))
- $attachmentType = "audio";
- else
- $this->fail(205, "Unknown attachment type");
-
- $attachment = str_replace($attachmentType, "", $attac);
-
- $attachmentOwner = (int)explode("_", $attachment)[0];
- $attachmentId = (int)end(explode("_", $attachment));
-
- $attacc = NULL;
-
- if($attachmentType == "photo") {
- $attacc = (new PhotosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Photo does not exists");
- if(!$attacc->getOwner()->getPrivacyPermission('photos.read', $this->getUser()))
- $this->fail(11, "Access to photo denied");
-
- $comment->attach($attacc);
- } elseif($attachmentType == "video") {
- $attacc = (new VideosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Video does not exists");
- if(!$attacc->getOwner()->getPrivacyPermission('videos.read', $this->getUser()))
- $this->fail(11, "Access to video denied");
-
- $comment->attach($attacc);
- } elseif($attachmentType == "audio") {
- $attacc = (new AudiosRepo)->getByOwnerAndVID($attachmentOwner, $attachmentId);
- if(!$attacc || $attacc->isDeleted())
- $this->fail(100, "Audio does not exist");
-
- $comment->attach($attacc);
- }
- }
+ foreach($final_attachments as $attachment) {
+ $comment->attach($attachment);
}
if($post->getOwner()->getId() !== $this->user->getId())
@@ -1048,25 +949,20 @@ final class Wall extends VKAPIRequestHandler
}
$post->save(true);
+
+ $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']);
+ $final_attachments = [];
+ foreach($parsed_attachments as $attachment) {
+ if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) &&
+ !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) {
+ $final_attachments[] = $attachment;
+ }
+ }
- # todo добавить такое в веб версию
- if(!empty($attachments)) {
- $attachs = parseAttachments($attachments);
- $newAttachmentsCount = sizeof($attachs);
-
- $postsAttachments = iterator_to_array($post->getChildren());
-
- if(sizeof($postsAttachments) >= 10)
- $this->fail(15, "Post have too many attachments");
-
- if(($newAttachmentsCount + sizeof($postsAttachments)) > 10)
- $this->fail(158, "Post will have too many attachments");
-
- foreach($attachs as $attach) {
- if($attach && !$attach->isDeleted())
- $post->attach($attach);
- else
- $this->fail(52, "One of the attachments is invalid");
+ if(sizeof($final_attachments) > 0) {
+ $post->unwire();
+ foreach($final_attachments as $attachment) {
+ $post->attach($attachment);
}
}
@@ -1093,24 +989,20 @@ final class Wall extends VKAPIRequestHandler
$comment->setEdited(time());
$comment->save(true);
-
- if(!empty($attachments)) {
- $attachs = parseAttachments($attachments);
- $newAttachmentsCount = sizeof($attachs);
- $postsAttachments = iterator_to_array($comment->getChildren());
+ $parsed_attachments = parseAttachments($attachments, ['photo', 'video', 'note', 'audio']);
+ $final_attachments = [];
+ foreach($parsed_attachments as $attachment) {
+ if($attachment && !$attachment->isDeleted() && $attachment->canBeViewedBy($this->getUser()) &&
+ !(method_exists($attachment, 'getVoters') && $attachment->getOwner()->getId() != $this->getUser()->getId())) {
+ $final_attachments[] = $attachment;
+ }
+ }
- if(sizeof($postsAttachments) >= 10)
- $this->fail(15, "Post have too many attachments");
-
- if(($newAttachmentsCount + sizeof($postsAttachments)) > 10)
- $this->fail(158, "Post will have too many attachments");
-
- foreach($attachs as $attach) {
- if($attach && !$attach->isDeleted())
- $comment->attach($attach);
- else
- $this->fail(52, "One of the attachments is invalid");
+ if(sizeof($final_attachments) > 0) {
+ $comment->unwire();
+ foreach($final_attachments as $attachment) {
+ $comment->attach($attachment);
}
}
diff --git a/Web/Models/Repositories/Videos.php b/Web/Models/Repositories/Videos.php
index e91c226d..e78a1b0f 100644
--- a/Web/Models/Repositories/Videos.php
+++ b/Web/Models/Repositories/Videos.php
@@ -39,6 +39,13 @@ class Videos
$perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE;
foreach($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->page($page, $perPage)->order("created DESC") as $video)
yield new Video($video);
+ }
+
+ function getByUserLimit(User $user, int $offset = 0, int $limit = 10): \Traversable
+ {
+ $perPage = $perPage ?? OPENVK_DEFAULT_PER_PAGE;
+ foreach($this->videos->where("owner", $user->getId())->where(["deleted" => 0, "unlisted" => 0])->limit($limit, $offset)->order("created DESC") as $video)
+ yield new Video($video);
}
function getUserVideosCount(User $user): int
diff --git a/Web/Presenters/CommentPresenter.php b/Web/Presenters/CommentPresenter.php
index 741a03e6..7ab74ac0 100644
--- a/Web/Presenters/CommentPresenter.php
+++ b/Web/Presenters/CommentPresenter.php
@@ -79,15 +79,15 @@ final class CommentPresenter extends OpenVKPresenter
$horizontal_attachments = [];
$vertical_attachments = [];
if(!empty($this->postParam("horizontal_attachments"))) {
- $horizontal_attachments_array = explode(",", $this->postParam("horizontal_attachments"));
- if(sizeof($horizontal_attachments_array) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]) {
+ $horizontal_attachments_array = array_slice(explode(",", $this->postParam("horizontal_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]);
+ if(sizeof($horizontal_attachments_array) > 0) {
$horizontal_attachments = parseAttachments($horizontal_attachments_array, ['photo', 'video']);
}
}
if(!empty($this->postParam("vertical_attachments"))) {
- $vertical_attachments_array = explode(",", $this->postParam("vertical_attachments"));
- if(sizeof($vertical_attachments_array) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]) {
+ $vertical_attachments_array = array_slice(explode(",", $this->postParam("vertical_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]);
+ if(sizeof($vertical_attachments_array) > 0) {
$vertical_attachments = parseAttachments($vertical_attachments_array, ['audio', 'note']);
}
}
diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php
index 8a68d427..13df558d 100644
--- a/Web/Presenters/WallPresenter.php
+++ b/Web/Presenters/WallPresenter.php
@@ -275,15 +275,15 @@ final class WallPresenter extends OpenVKPresenter
$horizontal_attachments = [];
$vertical_attachments = [];
if(!empty($this->postParam("horizontal_attachments"))) {
- $horizontal_attachments_array = explode(",", $this->postParam("horizontal_attachments"));
- if(sizeof($horizontal_attachments_array) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]) {
+ $horizontal_attachments_array = array_slice(explode(",", $this->postParam("horizontal_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]);
+ if(sizeof($horizontal_attachments_array) > 0) {
$horizontal_attachments = parseAttachments($horizontal_attachments_array, ['photo', 'video']);
}
}
if(!empty($this->postParam("vertical_attachments"))) {
- $vertical_attachments_array = explode(",", $this->postParam("vertical_attachments"));
- if(sizeof($vertical_attachments_array) <= OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]) {
+ $vertical_attachments_array = array_slice(explode(",", $this->postParam("vertical_attachments")), 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]);
+ if(sizeof($vertical_attachments_array) > 0) {
$vertical_attachments = parseAttachments($vertical_attachments_array, ['audio', 'note']);
}
}
diff --git a/Web/Presenters/templates/Audio/player.xml b/Web/Presenters/templates/Audio/player.xml
index de8f03d7..d94341d2 100644
--- a/Web/Presenters/templates/Audio/player.xml
+++ b/Web/Presenters/templates/Audio/player.xml
@@ -5,17 +5,17 @@
getPrettyId()}" data-name="{$audio->getName()}"{/if} data-genre="{$audio->getGenre()}" class="audioEmbed {if !$isAvailable}processed{/if} {if $isWithdrawn}withdrawn{/if}" data-length="{$audio->getLength()}" data-keys="{json_encode($audio->getKeys())}" data-url="{$audio->getURL()}">
-
-
+
+
-
+
-
-
{$audio->getFormattedLength()}
+
+
{$audio->getFormattedLength()}
{php $hasAudio = isset($thisUser) && $audio->isInLibraryOf($thisUser)}
@@ -44,7 +44,7 @@
-
+
diff --git a/Web/Presenters/templates/components/textArea.xml b/Web/Presenters/templates/components/textArea.xml
index a3b7bfa0..b01758f9 100644
--- a/Web/Presenters/templates/components/textArea.xml
+++ b/Web/Presenters/templates/components/textArea.xml
@@ -54,8 +54,8 @@
{_comment_as_group}
-
-
+
+
@@ -75,11 +75,11 @@
{_photo}
-
+
{_video}
-
+
{_audio}
diff --git a/Web/static/css/audios.css b/Web/static/css/audios.css
index d3c1bdf1..a834b773 100644
--- a/Web/static/css/audios.css
+++ b/Web/static/css/audios.css
@@ -267,6 +267,17 @@
color: white;
}
+.audioEntry .volume {
+ display: flex;
+ flex-direction: column;
+ width: 14%;
+}
+
+.audioEntry .nobold {
+ text-align: center;
+ margin-top: 12px;
+}
+
.audioEntry.nowPlaying .volume .nobold {
color: white !important;
}
@@ -303,6 +314,7 @@
height: 100%;
position: relative;
width: 100%;
+ min-height: 39px;
}
.audioEntry .playerButton {
@@ -341,6 +353,7 @@
grid-template-columns: 1fr;
width: 85%;
height: 23px;
+ margin-top: 12px;
}
.audioEntry .status .mediaInfo {
@@ -588,7 +601,6 @@
}
.attachAudio {
- float: left;
width: 28%;
height: 26px;
padding-top: 11px;
diff --git a/Web/static/css/main.css b/Web/static/css/main.css
index ab108b24..04c56408 100644
--- a/Web/static/css/main.css
+++ b/Web/static/css/main.css
@@ -1490,7 +1490,7 @@ body.scrolled .toTop:hover {
color: #3c3c3c;
}
-.post-source #remove_source_button {
+.post-source #remove_source_button, #small_remove_button {
display: inline-block;
background-repeat: no-repeat;
background: url('/assets/packages/static/openvk/img/arrows.png?v=2');
@@ -1504,7 +1504,7 @@ body.scrolled .toTop:hover {
cursor: pointer;
}
-.post-source #remove_source_button:hover {
+.post-source #remove_source_button:hover, #small_remove_button:hover {
opacity: 0.8;
}
@@ -2413,8 +2413,8 @@ a.poll-retract-vote {
}
}
-.post-horizontal {
- margin-top: 8px;
+.post-horizontal, .post-vertical {
+ margin-top: 0px;
}
.post-horizontal {
@@ -2424,19 +2424,46 @@ a.poll-retract-vote {
gap: 3px;
}
+.post-vertical {
+ display: flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ gap: 3px;
+}
+
.post-horizontal .upload-item {
/*width: 75px;
height: 60px;*/
overflow: hidden;
- display: inline-block;
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
position: relative;
}
-.post-horizontal .upload-item.dragged {
+.post-horizontal .upload-item .play-button {
+ position: absolute;
+ height: 30px;
+ width: 30px;
+ background: rgba(0, 0, 0, 0.8);
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.post-horizontal .upload-item .play-button .play-button-ico {
+ background: url(/assets/packages/static/openvk/img/wall.png) no-repeat 1px 0;
+ display: inline-block;
+ height: 15px;
+ width: 12px;
+}
+
+.upload-item.dragged {
filter: contrast(0.5);
}
-.upload-item .upload-delete {
+.post-horizontal .upload-item .upload-delete {
position: absolute;
background: rgba(0,0,0,0.5);
padding: 2px 5px;
@@ -2444,6 +2471,7 @@ a.poll-retract-vote {
color: #fff;
font-size: 11px;
right: 0px;
+ top: 0px;
opacity: 0;
transition: 0.25s;
}
@@ -2452,13 +2480,60 @@ a.poll-retract-vote {
opacity: 1;
}
-.upload-item img {
+.post-horizontal .upload-item img {
width: 100%;
max-height: 60px;
object-fit: cover;
border-radius: 3px;
}
+.post-vertical .vertical-attachment {
+ display: grid;
+ grid-template-columns: 1fr 0fr;
+}
+
+.post-vertical .vertical-attachment:first-of-type {
+ margin-top: 7px;
+}
+
+.post-vertical .vertical-attachment .audioEntry {
+ max-height: 28px;
+ min-height: 18px;
+}
+
+.post-vertical .vertical-attachment .audioEntry .playerButton {
+ padding: 0px 3px 0px 3px;
+}
+
+.post-vertical .vertical-attachment .audioEntry .status {
+ margin-top: 1px;
+ margin-left: 2px;
+ height: 15px;
+}
+
+.post-vertical .vertical-attachment .audioEntry .nobold {
+ margin-top: 1px;
+}
+
+.post-vertical .vertical-attachment .audioEntry .subTracks {
+ padding-bottom: 2px;
+ padding-left: 3px;
+ padding-right: 0px;
+}
+
+.post-vertical .vertical-attachment .audioEntry .audioEntryWrapper {
+ height: 18px;
+}
+
+.post-vertical .vertical-attachment .vertical-attachment-content {
+ max-height: 27px;
+}
+
+.post-vertical .vertical-attachment .vertical-attachment-content .overflowedName {
+ position: initial;
+ width: 100% !important;
+}
+
/* https://imgur.com/a/ihB3JZ4 */
.ovk-photo-view-dimmer {
@@ -3169,6 +3244,10 @@ body.article .floating_sidebar, body.article .page_content {
justify-content: space-between;
}
+.attachment_selector .topGrayBlock #video_query {
+ width: 160px;
+}
+
.attachment_selector .topGrayBlock #albumSelect {
width: 150px;
}
@@ -3216,6 +3295,22 @@ body.article .floating_sidebar, body.article .page_content {
margin: unset;
}
+.attachment_selector #attachment_insert .videosInsert .video_list .video-preview {
+ height: 75px;
+ width: 133px;
+ overflow: hidden;
+}
+
+.attachment_selector #attachment_insert .videosInsert .video_list .video-preview img {
+ max-width: 133px;
+ height: 75px;
+ margin: auto;
+}
+
+.attachment_selector #attachment_insert .videosInsert .video_list .action_links {
+ width: 150px;
+}
+
.edited {
color: #9b9b9b;
}
diff --git a/Web/static/img/audio.png b/Web/static/img/audio.png
deleted file mode 100644
index 62d9dff2..00000000
Binary files a/Web/static/img/audio.png and /dev/null differ
diff --git a/Web/static/img/favicons/favicon24_paused.png b/Web/static/img/favicons/favicon24_paused.png
index c8fdef26..ce4478b8 100644
Binary files a/Web/static/img/favicons/favicon24_paused.png and b/Web/static/img/favicons/favicon24_paused.png differ
diff --git a/Web/static/img/favicons/favicon24_playing.png b/Web/static/img/favicons/favicon24_playing.png
index ce4478b8..c8fdef26 100644
Binary files a/Web/static/img/favicons/favicon24_playing.png and b/Web/static/img/favicons/favicon24_playing.png differ
diff --git a/Web/static/img/miniplayer_close.png b/Web/static/img/miniplayer_close.png
deleted file mode 100644
index e2f0fb78..00000000
Binary files a/Web/static/img/miniplayer_close.png and /dev/null differ
diff --git a/Web/static/img/miniplayer_open.png b/Web/static/img/miniplayer_open.png
deleted file mode 100644
index 7f442647..00000000
Binary files a/Web/static/img/miniplayer_open.png and /dev/null differ
diff --git a/Web/static/img/note.svg b/Web/static/img/note.svg
deleted file mode 100644
index 9583bb3b..00000000
--- a/Web/static/img/note.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/Web/static/img/video.png b/Web/static/img/video.png
deleted file mode 100644
index 5c115f1c..00000000
Binary files a/Web/static/img/video.png and /dev/null differ
diff --git a/Web/static/img/wall.png b/Web/static/img/wall.png
new file mode 100644
index 00000000..70cd42c0
Binary files /dev/null and b/Web/static/img/wall.png differ
diff --git a/Web/static/js/al_music.js b/Web/static/js/al_music.js
index f25518b4..6c37347c 100644
--- a/Web/static/js/al_music.js
+++ b/Web/static/js/al_music.js
@@ -1315,8 +1315,8 @@ $(document).on("click", "#_deletePlaylist", (e) => {
}, Function.noop])
})
-$(document).on("click", "#_audioAttachment", (e) => {
- let form = e.currentTarget.closest("form")
+$(document).on("click", "#__audioAttachment", (e) => {
+ const form = e.target.closest("form")
let body = `
@@ -1328,7 +1328,7 @@ $(document).on("click", "#_audioAttachment", (e) => {
`
- MessageBox(tr("select_audio"), body, [tr("ok")], [Function.noop])
+ MessageBox(tr("select_audio"), body, [tr("close")], [Function.noop])
document.querySelector(".ovk-diag-body").style.padding = "0"
document.querySelector(".ovk-diag-cont").style.width = "580px"
@@ -1349,23 +1349,24 @@ $(document).on("click", "#_audioAttachment", (e) => {
result.querySelectorAll(".audioEmbed").forEach(el => {
let id = el.dataset.prettyid
- let name = el.dataset.name
- let isAttached = (form.querySelector("input[name='audios']").value.includes(`${id},`))
+ const is_attached = (u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`)).length > 0
+
document.querySelector(".audiosInsert").insertAdjacentHTML("beforeend", `
-
-
${el.outerHTML}
-
-
${isAttached ? tr("detach_audio") : tr("attach_audio")}
+
`)
})
u("#loader").remove()
+ u('#show_more').remove()
if(thisc.page < pagesCount) {
document.querySelector(".audiosInsert").insertAdjacentHTML("beforeend", `
-
+
${tr("show_more_audios")}
`)
}
@@ -1385,14 +1386,12 @@ $(document).on("click", "#_audioAttachment", (e) => {
searcher.movePage(1)
- $(".audiosInsert").on("click", "#showMoreAudios", (e) => {
- u(e.currentTarget).remove()
+ u(".audiosInsert").on("click", "#show_more", async (e) => {
+ u(e.target).closest('#show_more').addClass('lagged')
searcher.movePage(Number(e.currentTarget.dataset.page))
})
$(".searchBox input").on("change", async (e) => {
- await new Promise(r => setTimeout(r, 500));
-
if(e.currentTarget.value === document.querySelector(".searchBox input").value) {
searcher.clearContainer()
@@ -1423,44 +1422,34 @@ $(document).on("click", "#_audioAttachment", (e) => {
return;
})
- function insertAttachment(id) {
- let audios = form.querySelector("input[name='audios']")
+ u(".audiosInsert").on("click", ".attachAudio", (ev) => {
+ const id = ev.currentTarget.dataset.attachmentdata
+ const is_attached = u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`).length > 0
- if(!audios.value.includes(id + ",")) {
- if(audios.value.split(",").length > 10) {
- NewNotification(tr("error"), tr("max_attached_audios"))
- return false
+ // 04.11.2024 19:03
+ if(is_attached) {
+ u(form).find(`.post-vertical .vertical-attachment[data-id='${id}']`).remove()
+ u(ev.currentTarget).find("span").html(tr("attach_audio"))
+ } else {
+ if(u(form).find(`.vertical-attachment`).length > window.openvk.max_attachments) {
+ makeError(tr('too_many_attachments'), 'Red', 10000, 1)
+ return
}
- form.querySelector("input[name='audios']").value += (id + ",")
+ u(ev.currentTarget).find("span").html(tr("detach_audio"))
- return true
- } else {
- form.querySelector("input[name='audios']").value = form.querySelector("input[name='audios']").value.replace(id + ",", "")
-
- return false
- }
- }
-
- $(".audiosInsert").on("click", ".attachAudio", (ev) => {
- if(!insertAttachment(ev.currentTarget.dataset.attachmentdata)) {
- u(`.post-has-audios .post-has-audio[data-id='${ev.currentTarget.dataset.attachmentdata}']`).remove()
- ev.currentTarget.querySelector("span").innerHTML = tr("attach_audio")
- } else {
- ev.currentTarget.querySelector("span").innerHTML = tr("detach_audio")
-
- form.querySelector(".post-has-audios").insertAdjacentHTML("beforeend", `
-
-
${ovk_proc_strtr(escapeHtml(ev.currentTarget.dataset.name), 40)}
+ const header = u(ev.currentTarget).closest('.audio_attachment_header')
+ const player = header.find('.player_part')
+ u(form).find(".post-vertical").append(`
+
`)
-
- u(`#unattachAudio[data-id='${ev.currentTarget.dataset.attachmentdata}']`).on("click", (e) => {
- let id = ev.currentTarget.dataset.attachmentdata
- form.querySelector("input[name='audios']").value = form.querySelector("input[name='audios']").value.replace(id + ",", "")
-
- u(e.currentTarget).remove()
- })
}
})
})
diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js
index b662ff85..6ec92934 100644
--- a/Web/static/js/al_wall.js
+++ b/Web/static/js/al_wall.js
@@ -512,14 +512,10 @@ async function __appendToTextarea(attachment_obj, textareaNode) {
indicator.append(`
×
+ ${attachment_obj.type == 'video' ? `` : ''}
`)
-
- u(document).on('click', `.post-horizontal .upload-item[data-id='${attachment_obj.id}'] .upload-delete`, (e) => {
- e.preventDefault()
- indicator.find(`.upload-item[data-id='${attachment_obj.id}']`).remove()
- })
}
// ajax не буде работать
@@ -531,13 +527,14 @@ u('#write .small-textarea').on('paste', (e) => {
}
})
-u('#write').on('dragstart', '.post-horizontal .upload-item', (e) => {
+u('#write').on('dragstart', '.post-horizontal .upload-item, .post-vertical .upload-item > *', (e) => {
//e.preventDefault()
- u(e.target).addClass('currently_dragging')
+ //console.log(e)
+ u(e.target).closest('.upload-item').addClass('currently_dragging')
return
})
-u('#write').on('dragover', '.post-horizontal .upload-item', (e) => {
+u('#write').on('dragover', '.post-horizontal .upload-item, .post-vertical .upload-item > *', (e) => {
e.preventDefault()
const target = u(e.target).closest('.upload-item')
@@ -550,23 +547,31 @@ u('#write').on('dragover', '.post-horizontal .upload-item', (e) => {
return
})
-u('#write').on('dragleave dragend', '.post-horizontal .upload-item', (e) => {
+u('#write').on('dragleave dragend', '.post-horizontal .upload-item, .post-vertical .upload-item > *', (e) => {
+ //console.log(e)
u(e.target).closest('.upload-item').removeClass('dragged')
return
})
u('#write').on("drop", function(e) {
- e.preventDefault()
-
const current = u('.upload-item.currently_dragging')
-
+ //console.log(e)
if(e.dataTransfer.types.includes('Files')) {
+ e.preventDefault()
+
e.dataTransfer.dropEffect = 'move'
__uploadToTextarea(e.dataTransfer.files[0], u(e.target).closest('#write'))
- } else {
+ } else if(e.dataTransfer.types.length < 1 || e.dataTransfer.types.includes('text/uri-list')) {
+ e.preventDefault()
+
const target = u(e.target).closest('.upload-item')
- target.removeClass('dragged')
+ u('.dragged').removeClass('dragged')
current.removeClass('currently_dragging')
+ //console.log(target)
+ if(!current.closest('.vertical-attachment').length < 1 && target.closest('.vertical-attachment').length < 1
+ || current.closest('.vertical-attachment').length < 1 && !target.closest('.vertical-attachment').length < 1) {
+ return
+ }
const first_html = target.nodes[0].outerHTML
const second_html = current.nodes[0].outerHTML
@@ -581,14 +586,14 @@ u('#write > form').on('submit', (e) => {
const horizontal_array = []
const horizontal_input = target.find(`input[name='horizontal_attachments']`)
const horizontal_attachments = target.find(`.post-horizontal > a`)
- horizontal_attachments.nodes.slice(0, window.openvk.max_attachments).forEach(_node => {
+ horizontal_attachments.nodes.forEach(_node => {
horizontal_array.push(`${_node.dataset.type}${_node.dataset.id}`)
})
horizontal_input.nodes[0].value = horizontal_array.join(',')
const vertical_array = []
const vertical_input = target.find(`input[name='vertical_attachments']`)
- const vertical_attachments = target.find(`.post-vertical > a`)
+ const vertical_attachments = target.find(`.post-vertical > .vertical-attachment`)
vertical_attachments.nodes.forEach(_node => {
vertical_array.push(`${_node.dataset.type}${_node.dataset.id}`)
})
@@ -732,6 +737,171 @@ u(document).on("click", "#__photoAttachment", async (e) => {
})
})
+u(document).on('click', '#__videoAttachment', async (e) => {
+ const per_page = 10
+ const form = u(e.target).closest('form')
+ const msg = new CMessageBox({
+ title: tr('selecting_video'),
+ body: `
+
+ `,
+ buttons: [tr('close')],
+ callbacks: [Function.noop]
+ })
+
+ msg.getNode().attr('style', 'width: 630px;')
+ msg.getNode().find('.ovk-diag-body').attr('style', 'height:335px;padding:0px;')
+
+ async function __recieveVideos(page, query = '') {
+ u('#gif_loader').remove()
+ u('#attachment_insert').append(`
`)
+ const insert_place = u('#attachment_insert .videosInsert')
+ let videos = null
+
+ try {
+ if(query == '') {
+ videos = await window.OVKAPI.call('video.get', {'owner_id': window.openvk.current_id, 'extended': 1, 'count': per_page, 'offset': page * per_page})
+ } else {
+ videos = await window.OVKAPI.call('video.search', {'q': escapeHtml(query), 'extended': 1, 'count': per_page, 'offset': page * per_page})
+ }
+ } catch(e) {
+ u("#gif_loader").remove()
+ insert_place.html("Err")
+ return
+ }
+
+ u("#gif_loader").remove()
+ const pages_count = Math.ceil(Number(videos.count) / per_page)
+ videos.items.forEach(video => {
+ const pretty_id = `${video.owner_id}_${video.id}`
+ const is_attached = (form.find(`.upload-item[data-type='video'][data-id='${video.owner_id}_${video.id}']`)).length > 0
+ let author_name = ''
+
+ const profiles = videos.profiles
+ const groups = videos.groups
+
+ if(video['owner_id'] > 0) {
+ const profile = profiles.find(prof => prof.id == video['owner_id'])
+ if(profile) {
+ author_name = profile['first_name'] + ' ' + profile['last_name']
+ }
+ } else {
+ const group = groups.find(grou => grou.id == Math.abs(video['owner_id']))
+ if(group) {
+ author_name = group['name']
+ }
+ }
+
+ insert_place.append(`
+
+ `)
+ })
+
+ if(page < pages_count - 1) {
+ insert_place.append(`
+
+ ${tr('show_more')}
+
`)
+ }
+
+ if(query != '') {
+ highlightText(query, '.videosInsert', ['.video-name', '.video-desc'])
+ }
+ }
+
+ u(".ovk-diag-body #video_query").on('change', (ev) => {
+ if(ev.target.value == u(".ovk-diag-body #video_query").nodes[0].value) {
+ u('#attachment_insert .videosInsert').html('')
+ __recieveVideos(0, u(".ovk-diag-body #video_query").nodes[0].value)
+ }
+ })
+
+ // next page
+ u(".ovk-diag-body .attachment_selector").on("click", "#show_more", async (ev) => {
+ const target = u(ev.target).closest('#show_more')
+ target.addClass('lagged')
+ await __recieveVideos(Number(target.nodes[0].dataset.page), u(".topGrayBlock #video_query").nodes[0].value)
+ target.remove()
+ })
+
+ // add video
+ u(".ovk-diag-body .attachment_selector").on("click", "#__attach_vid", async (ev) => {
+ ev.preventDefault()
+
+ const target = u(ev.target).closest('.content')
+ const button = target.find('#__attach_vid')
+ const dataset = target.nodes[0].dataset
+ const is_attached = (form.find(`.upload-item[data-type='video'][data-id='${dataset.attachmentdata}']`)).length > 0
+ if(is_attached) {
+ (form.find(`.upload-item[data-type='video'][data-id='${dataset.attachmentdata}']`)).remove()
+ button.html(tr('attach'))
+ } else {
+ if(form.find(`.upload-item`).length + 1 > window.openvk.max_attachments) {
+ makeError(tr('too_many_attachments'), 'Red', 10000, 1)
+ return
+ }
+
+ button.html(tr('detach'))
+ __appendToTextarea({
+ 'type': 'video',
+ 'preview': dataset.preview,
+ 'id': dataset.attachmentdata,
+ 'fullsize_url': dataset.preview,
+ }, form)
+ }
+ })
+
+ __recieveVideos(0)
+})
+
+u(document).on('click', `.post-horizontal .upload-item .upload-delete`, (e) => {
+ e.preventDefault()
+ u(e.target).closest('.upload-item').remove()
+})
+
+u(document).on('click', `.post-vertical .vertical-attachment #small_remove_button`, (e) => {
+ e.preventDefault()
+ u(e.target).closest('.vertical-attachment').remove()
+})
+
u(document).on('click', '.post-buttons .upload-item', (e) => {
e.preventDefault()
})
diff --git a/Web/static/js/utils.js b/Web/static/js/utils.js
index 4e0c4977..10990c70 100644
--- a/Web/static/js/utils.js
+++ b/Web/static/js/utils.js
@@ -28,7 +28,7 @@ function highlightText(searchText, container_selector, selectors = []) {
node.parentNode.insertBefore(tempDiv.firstChild, node)
}
node.parentNode.removeChild(node)
- } else if(node.nodeType === 1 && node.tagName !== 'SCRIPT' && node.tagName !== 'BR' && node.tagName !== 'STYLE') {
+ } else if(node.nodeType === 1 && node.tagName !== 'SCRIPT' && node.tagName !== 'BR' && node.tagName !== 'STYLE' && !node.classList.contains('highlight')) {
Array.from(node.childNodes).forEach(highlightNode);
}
}
diff --git a/bootstrap.php b/bootstrap.php
index 7b22115b..405dc2fb 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -235,6 +235,7 @@ function ovk_is_ssl(): bool
function parseAttachments($attachments, array $allow_types = ['photo', 'video', 'note', 'audio']): array
{
$exploded_attachments = is_array($attachments) ? $attachments : explode(",", $attachments);
+ $exploded_attachments = array_slice($exploded_attachments, 0, OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["postSizes"]["maxAttachments"]);
$imploded_types = implode('|', $allow_types);
$output_attachments = [];
$repositories = [
@@ -254,21 +255,37 @@ function parseAttachments($attachments, array $allow_types = ['photo', 'video',
'repo' => 'openvk\Web\Models\Repositories\Notes',
'method' => 'getNoteById',
],
+ 'poll' => [
+ 'repo' => 'openvk\Web\Models\Repositories\Polls',
+ 'method' => 'get',
+ 'onlyId' => true,
+ ],
];
foreach($exploded_attachments as $attachment_string) {
if(preg_match("/$imploded_types/", $attachment_string, $matches) == 1) {
- $attachment_type = $matches[0];
- if(!$repositories[$attachment_type])
- continue;
-
- $attachment_ids = str_replace($attachment_type, '', $attachment_string);
- [$attachment_owner, $attachment_id] = array_map('intval', explode('_', $attachment_ids));
-
- $repository_class = $repositories[$attachment_type]['repo'];
- if(!$repository_class) continue;
- $attachment_model = (new $repository_class)->{$repositories[$attachment_type]['method']}($attachment_owner, $attachment_id);
- $output_attachments[] = $attachment_model;
+ try {
+ $attachment_type = $matches[0];
+ if(!$repositories[$attachment_type])
+ continue;
+
+ $attachment_ids = str_replace($attachment_type, '', $attachment_string);
+ if($repositories[$attachment_type]['onlyId']) {
+ [$attachment_id] = array_map('intval', explode('_', $attachment_ids));
+
+ $repository_class = $repositories[$attachment_type]['repo'];
+ if(!$repository_class) continue;
+ $attachment_model = (new $repository_class)->{$repositories[$attachment_type]['method']}($attachment_id);
+ $output_attachments[] = $attachment_model;
+ } else {
+ [$attachment_owner, $attachment_id] = array_map('intval', explode('_', $attachment_ids));
+
+ $repository_class = $repositories[$attachment_type]['repo'];
+ if(!$repository_class) continue;
+ $attachment_model = (new $repository_class)->{$repositories[$attachment_type]['method']}($attachment_owner, $attachment_id);
+ $output_attachments[] = $attachment_model;
+ }
+ } catch(\Throwable) {continue;}
}
}