mirror of
https://github.com/openvk/openvk
synced 2024-12-22 16:42:32 +03:00
Wall: add notes attachments to posts (#907)
* Posts: add notes attachments
This commit is contained in:
parent
b35b87567b
commit
2e76ca16df
14 changed files with 220 additions and 10 deletions
|
@ -2,17 +2,19 @@
|
|||
namespace openvk\ServiceAPI;
|
||||
use openvk\Web\Models\Entities\Post;
|
||||
use openvk\Web\Models\Entities\User;
|
||||
use openvk\Web\Models\Repositories\Posts;
|
||||
use openvk\Web\Models\Repositories\{Posts, Notes};
|
||||
|
||||
class Wall implements Handler
|
||||
{
|
||||
protected $user;
|
||||
protected $posts;
|
||||
protected $notes;
|
||||
|
||||
function __construct(?User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->posts = new Posts;
|
||||
$this->notes = new Notes;
|
||||
}
|
||||
|
||||
function getPost(int $id, callable $resolve, callable $reject): void
|
||||
|
@ -71,4 +73,25 @@ class Wall implements Handler
|
|||
|
||||
$resolve($post->getId());
|
||||
}
|
||||
|
||||
function getMyNotes(callable $resolve, callable $reject)
|
||||
{
|
||||
$myNotes = $this->notes->getUserNotes($this->user, 1, $this->notes->getUserNotesCount($this->user));
|
||||
|
||||
$arr = [
|
||||
"count" => sizeof($myNotes),
|
||||
"closed" => $this->user->getPrivacySetting("notes.read"),
|
||||
"items" => [],
|
||||
];
|
||||
|
||||
foreach($myNotes as $note) {
|
||||
$arr["items"][] = [
|
||||
"id" => $note->getId(),
|
||||
"name" => ovk_proc_strtr($note->getName(), 30),
|
||||
#"preview" => $note->getPreview()
|
||||
];
|
||||
}
|
||||
|
||||
$resolve($arr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,9 @@ final class Notes extends VKAPIRequestHandler
|
|||
if($note->getOwner()->isDeleted())
|
||||
$this->fail(403, "Owner is deleted");
|
||||
|
||||
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
|
||||
$this->fail(43, "No access");
|
||||
|
||||
if(empty($message) && empty($attachments))
|
||||
$this->fail(100, "Required parameter 'message' missing.");
|
||||
|
||||
|
@ -183,6 +186,9 @@ final class Notes extends VKAPIRequestHandler
|
|||
if(!$user || $user->isDeleted())
|
||||
$this->fail(15, "Invalid user");
|
||||
|
||||
if(!$user->getPrivacyPermission('notes.read', $this->getUser()))
|
||||
$this->fail(43, "Access denied: this user chose to hide his notes");
|
||||
|
||||
if(empty($note_ids)) {
|
||||
$notes = array_slice(iterator_to_array((new NotesRepo)->getUserNotes($user, 1, $count + $offset, $sort == 0 ? "ASC" : "DESC")), $offset);
|
||||
$nodez = (object) [
|
||||
|
@ -225,10 +231,13 @@ final class Notes extends VKAPIRequestHandler
|
|||
|
||||
if($note->isDeleted())
|
||||
$this->fail(189, "Note is deleted");
|
||||
|
||||
|
||||
if(!$note->getOwner() || $note->getOwner()->isDeleted())
|
||||
$this->fail(177, "Owner does not exists");
|
||||
|
||||
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
|
||||
$this->fail(40, "Access denied: this user chose to hide his notes");
|
||||
|
||||
return $note->toVkApiStruct();
|
||||
}
|
||||
|
||||
|
@ -246,6 +255,9 @@ final class Notes extends VKAPIRequestHandler
|
|||
|
||||
if(!$note->getOwner())
|
||||
$this->fail(177, "Owner does not exists");
|
||||
|
||||
if(!$note->getOwner()->getPrivacyPermission('notes.read', $this->getUser()))
|
||||
$this->fail(14, "No access");
|
||||
|
||||
$arr = (object) [
|
||||
"count" => $note->getCommentsCount(),
|
||||
|
|
|
@ -13,6 +13,8 @@ use openvk\Web\Models\Entities\Photo;
|
|||
use openvk\Web\Models\Repositories\Photos as PhotosRepo;
|
||||
use openvk\Web\Models\Entities\Video;
|
||||
use openvk\Web\Models\Repositories\Videos as VideosRepo;
|
||||
use openvk\Web\Models\Entities\Note;
|
||||
use openvk\Web\Models\Repositories\Notes as NotesRepo;
|
||||
|
||||
final class Wall extends VKAPIRequestHandler
|
||||
{
|
||||
|
@ -54,6 +56,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
$attachments[] = $this->getApiPoll($attachment, $this->getUser());
|
||||
} else if ($attachment instanceof \openvk\Web\Models\Entities\Video) {
|
||||
$attachments[] = $attachment->getApiStructure();
|
||||
} else if ($attachment instanceof \openvk\Web\Models\Entities\Note) {
|
||||
$attachments[] = $attachment->toVkApiStruct();
|
||||
} else if ($attachment instanceof \openvk\Web\Models\Entities\Post) {
|
||||
$repostAttachments = [];
|
||||
|
||||
|
@ -226,6 +230,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
$attachments[] = $this->getApiPoll($attachment, $user);
|
||||
} else if ($attachment instanceof \openvk\Web\Models\Entities\Video) {
|
||||
$attachments[] = $attachment->getApiStructure();
|
||||
} else if ($attachment instanceof \openvk\Web\Models\Entities\Note) {
|
||||
$attachments[] = $attachment->toVkApiStruct();
|
||||
} else if ($attachment instanceof \openvk\Web\Models\Entities\Post) {
|
||||
$repostAttachments = [];
|
||||
|
||||
|
@ -440,6 +446,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
$attachmentType = "photo";
|
||||
elseif(str_contains($attac, "video"))
|
||||
$attachmentType = "video";
|
||||
elseif(str_contains($attac, "note"))
|
||||
$attachmentType = "note";
|
||||
else
|
||||
$this->fail(205, "Unknown attachment type");
|
||||
|
||||
|
@ -465,6 +473,17 @@ final class Wall extends VKAPIRequestHandler
|
|||
if($attacc->getOwner()->getId() != $this->getUser()->getId())
|
||||
$this->fail(43, "You do not have access to this video");
|
||||
|
||||
$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()->getId() != $this->getUser()->getId())
|
||||
$this->fail(43, "You do not have access to this note");
|
||||
|
||||
if($attacc->getOwner()->getPrivacySetting("notes.read") < 1)
|
||||
$this->fail(11, "You can't attach note to post, because your notes list is closed. Change it in privacy settings in web-version.");
|
||||
|
||||
$post->attach($attacc);
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +561,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
foreach($comment->getChildren() as $attachment) {
|
||||
if($attachment instanceof \openvk\Web\Models\Entities\Photo) {
|
||||
$attachments[] = $this->getApiPhoto($attachment);
|
||||
} elseif($attachment instanceof \openvk\Web\Models\Entities\Note) {
|
||||
$attachments[] = $attachment->toVkApiStruct();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,8 +620,8 @@ final class Wall extends VKAPIRequestHandler
|
|||
function getComment(int $owner_id, int $comment_id, bool $extended = false, string $fields = "sex,screen_name,photo_50,photo_100,online_info,online") {
|
||||
$this->requireUser();
|
||||
|
||||
$comment = (new CommentsRepo)->get($comment_id); // один хуй айди всех комментов общий
|
||||
|
||||
$comment = (new CommentsRepo)->get($comment_id); # один хуй айди всех комментов общий
|
||||
|
||||
$profiles = [];
|
||||
|
||||
$attachments = [];
|
||||
|
|
|
@ -123,6 +123,7 @@ class Note extends Postable
|
|||
{
|
||||
$res = (object) [];
|
||||
|
||||
$res->type = "note";
|
||||
$res->id = $this->getId();
|
||||
$res->owner_id = $this->getOwner()->getId();
|
||||
$res->title = $this->getName();
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace openvk\Web\Presenters;
|
|||
use openvk\Web\Models\Exceptions\TooMuchOptionsException;
|
||||
use openvk\Web\Models\Entities\{Poll, Post, Photo, Video, Club, User};
|
||||
use openvk\Web\Models\Entities\Notifications\{MentionNotification, RepostNotification, WallPostNotification};
|
||||
use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums};
|
||||
use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums, Notes};
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
use Nette\InvalidStateException as ISE;
|
||||
use Bhaktaraz\RSSGenerator\Item;
|
||||
|
@ -278,8 +278,22 @@ final class WallPresenter extends OpenVKPresenter
|
|||
} catch(\UnexpectedValueException $e) {
|
||||
$this->flashFail("err", tr("failed_to_publish_post"), "Poll format invalid");
|
||||
}
|
||||
|
||||
$note = NULL;
|
||||
|
||||
if(!is_null($this->postParam("note")) && $this->postParam("note") != "none") {
|
||||
$note = (new Notes)->get((int)$this->postParam("note"));
|
||||
|
||||
if(!$note || $note->isDeleted() || $note->getOwner()->getId() != $this->user->id) {
|
||||
$this->flashFail("err", tr("error"), tr("error_attaching_note"));
|
||||
}
|
||||
|
||||
if($note->getOwner()->getPrivacySetting("notes.read") < 1) {
|
||||
$this->flashFail("err", " ");
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($this->postParam("text")) && !$photo && !$video && !$poll)
|
||||
if(empty($this->postParam("text")) && !$photo && !$video && !$poll && !$note)
|
||||
$this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_empty_or_too_big"));
|
||||
|
||||
try {
|
||||
|
@ -304,6 +318,9 @@ final class WallPresenter extends OpenVKPresenter
|
|||
|
||||
if(!is_null($poll))
|
||||
$post->attach($poll);
|
||||
|
||||
if(!is_null($note))
|
||||
$post->attach($note);
|
||||
|
||||
if($wall > 0 && $wall !== $this->user->identity->getId())
|
||||
(new WallPostNotification($wallOwner, $post, $this->user->identity))->emit();
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
|
||||
<div n:class="postFeedWrapper, $thisUser->hasMicroblogEnabled() ? postFeedWrapperMicroblog">
|
||||
{include "../components/textArea.xml", route => "/wall" . $thisUser->getId() . "/makePost", graffiti => true, polls => true}
|
||||
{include "../components/textArea.xml", route => "/wall" . $thisUser->getId() . "/makePost", graffiti => true, polls => true, notes => true}
|
||||
</div>
|
||||
|
||||
{foreach $posts as $post}
|
||||
|
|
|
@ -28,6 +28,20 @@
|
|||
</div>
|
||||
{elseif $attachment instanceof \openvk\Web\Models\Entities\Poll}
|
||||
{presenter "openvk!Poll->view", $attachment->getId()}
|
||||
{elseif $attachment instanceof \openvk\Web\Models\Entities\Note}
|
||||
{if !$attachment->isDeleted()}
|
||||
<div class="attachment_note">
|
||||
<img class="attachment_note_icon" src="/assets/packages/static/openvk/img/note.svg">
|
||||
<span class="attachment_note_text">{_note}</span>
|
||||
<span class="attachment_note_name"><a href="/note{$attachment->getPrettyId()}">{ovk_proc_strtr($attachment->getName(), 66)}</a></span>
|
||||
</div>
|
||||
{else}
|
||||
<div class="attachment_note">
|
||||
<img class="attachment_note_icon" src="/assets/packages/static/openvk/img/note.svg">
|
||||
<span class="attachment_note_text">{_note}</span>
|
||||
<span class="attachment_note_name">{_deleted}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{elseif $attachment instanceof \openvk\Web\Models\Entities\Post}
|
||||
{php $GLOBALS["_nesAttGloCou"] = (isset($GLOBALS["_nesAttGloCou"]) ? $GLOBALS["_nesAttGloCou"] : 0) + 1}
|
||||
{if $GLOBALS["_nesAttGloCou"] > 2}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
</div>
|
||||
<div class="post-has-poll">
|
||||
{_poll}
|
||||
</div>
|
||||
<div class="post-has-note">
|
||||
|
||||
</div>
|
||||
<div n:if="$postOpts ?? true" class="post-opts">
|
||||
{var $anonEnabled = OPENVK_ROOT_CONF['openvk']['preferences']['wall']['anonymousPosting']['enable']}
|
||||
|
@ -54,6 +57,7 @@
|
|||
<input type="file" class="postFileSel" id="postFilePic" name="_pic_attachment" accept="image/*" style="display:none;" />
|
||||
<input n:if="!OPENVK_ROOT_CONF['openvk']['preferences']['videos']['disableUploading']" type="file" class="postFileSel" id="postFileVid" name="_vid_attachment" accept="video/*" style="display:none;" />
|
||||
<input type="hidden" name="poll" value="none" />
|
||||
<input type="hidden" id="note" name="note" value="none" />
|
||||
<input type="hidden" name="type" value="1" />
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<br/>
|
||||
|
@ -75,6 +79,10 @@
|
|||
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/mimetypes/application-vnd.rn-realmedia.png" />
|
||||
{_video}
|
||||
</a>
|
||||
<a n:if="$notes ?? false" href="javascript:attachNote({$textAreaId})">
|
||||
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/mimetypes/application-x-srt.png" />
|
||||
{_note}
|
||||
</a>
|
||||
<a n:if="$graffiti ?? false" href="javascript:initGraffiti({$textAreaId});">
|
||||
<img src="/assets/packages/static/openvk/img/oxygen-icons/16x16/actions/draw-brush.png" />
|
||||
{_graffiti}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<div n:if="$canPost" class="content_subtitle">
|
||||
{include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true}
|
||||
{include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true, notes => true}
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
|
|
@ -1453,14 +1453,14 @@ body.scrolled .toTop:hover {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.post-upload, .post-has-poll {
|
||||
.post-upload, .post-has-poll, .post-has-note {
|
||||
margin-top: 11px;
|
||||
margin-left: 3px;
|
||||
color: #3c3c3c;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.post-upload::before, .post-has-poll::before {
|
||||
.post-upload::before, .post-has-poll::before, .post-has-note::before {
|
||||
content: " ";
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
|
@ -2533,3 +2533,35 @@ a.poll-retract-vote {
|
|||
{
|
||||
background: rgb(236, 235, 235);
|
||||
}
|
||||
|
||||
.attachment_note_icon {
|
||||
max-width: 9px;
|
||||
}
|
||||
|
||||
.attachment_note_text {
|
||||
color: #605F63;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.attachment_note {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#notesList
|
||||
{
|
||||
overflow-y: scroll;
|
||||
max-height: 130px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.ntSelect
|
||||
{
|
||||
cursor: pointer;
|
||||
padding: 6px;
|
||||
|
||||
}
|
||||
|
||||
.ntSelect:hover
|
||||
{
|
||||
background-color: rgb(233, 232, 232);
|
||||
}
|
||||
|
|
1
Web/static/img/note.svg
Normal file
1
Web/static/img/note.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg id="note" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 40"><defs><style>.cls-1{fill:#a0a0a0;}</style></defs><title>note</title><polygon class="cls-1" points="0 0 0 40 35 40 35 20 17.5 20 17.5 0 0 0"/><polygon id="block" class="cls-1" points="20.26 1 35 18 20.26 18 20.26 1"/></svg>
|
After Width: | Height: | Size: 292 B |
|
@ -189,3 +189,64 @@ tippy(".client_app", {
|
|||
}
|
||||
});
|
||||
|
||||
function addNote(textareaId, nid)
|
||||
{
|
||||
if(nid > 0) {
|
||||
note.value = nid
|
||||
let noteObj = document.querySelector("#nd"+nid)
|
||||
|
||||
let nortd = document.querySelector("#post-buttons"+textareaId+" .post-has-note");
|
||||
nortd.style.display = "block"
|
||||
|
||||
nortd.innerHTML = `${tr("note")} ${escapeHtml(noteObj.dataset.name)}`
|
||||
} else {
|
||||
note.value = "none"
|
||||
|
||||
let nortd = document.querySelector("#post-buttons"+textareaId+" .post-has-note");
|
||||
nortd.style.display = "none"
|
||||
|
||||
nortd.innerHTML = ""
|
||||
}
|
||||
|
||||
u("body").removeClass("dimmed");
|
||||
u(".ovk-diag-cont").remove();
|
||||
}
|
||||
|
||||
async function attachNote(id)
|
||||
{
|
||||
let notes = await API.Wall.getMyNotes()
|
||||
let body = ``
|
||||
|
||||
if(notes.closed < 1) {
|
||||
body = `${tr("notes_closed")}`
|
||||
} else {
|
||||
if(notes.items.length < 1) {
|
||||
body = `${tr("no_notes")}`
|
||||
} else {
|
||||
body = `
|
||||
${tr("select_or_create_new")}
|
||||
<div id="notesList">`
|
||||
|
||||
if(note.value != "none") {
|
||||
body += `
|
||||
<div class="ntSelect" onclick="addNote(${id}, 0)">
|
||||
<span>${tr("do_not_attach_note")}</span>
|
||||
</div>`
|
||||
}
|
||||
|
||||
for(const note of notes.items) {
|
||||
body += `
|
||||
<div data-name="${note.name}" class="ntSelect" id="nd${note.id}" onclick="addNote(${id}, ${note.id})">
|
||||
<span>${escapeHtml(note.name)}</span>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
body += `</div>`
|
||||
}
|
||||
}
|
||||
|
||||
let frame = MessageBox(tr("select_note"), body, [tr("cancel")], [Function.noop]);
|
||||
|
||||
document.querySelector(".ovk-diag-body").style.padding = "10px"
|
||||
}
|
|
@ -404,6 +404,16 @@
|
|||
"notes_list_one" = "$1 note found";
|
||||
"notes_list_other" = "$1 notes found";
|
||||
|
||||
"select_note" = "Selecting note";
|
||||
"no_notes" = "You don't have any notes";
|
||||
|
||||
"error_attaching_note" = "Error when attaching note";
|
||||
|
||||
"select_or_create_new" = "Select existing note or <a href='/notes/create'>create new one</a>";
|
||||
|
||||
"notes_closed" = "You can't attach note to post, because only you can see them.<br> You can change it in <a href=\"/settings?act=privacy\">settings</a>.";
|
||||
"do_not_attach_note" = "Do not attach note";
|
||||
|
||||
/* Menus */
|
||||
|
||||
/* Note that is string need to fit into the "My Page" link */
|
||||
|
|
|
@ -389,6 +389,16 @@
|
|||
"notes_list_many" = "Найдено $1 заметок";
|
||||
"notes_list_other" = "Найдено $1 заметок";
|
||||
|
||||
"select_note" = "Выбор заметки";
|
||||
"no_notes" = "У вас нет ни одной заметки";
|
||||
|
||||
"error_attaching_note" = "Не удалось прикрепить заметку";
|
||||
|
||||
"select_or_create_new" = "Выберите существующую заметку или <a href='/notes/create'>создайте новую</a>";
|
||||
|
||||
"notes_closed" = "Вы не можете прикрепить заметку к записи, так как ваши заметки видны только вам.<br><br> Вы можете поменять это в <a href=\"/settings?act=privacy\">настройках</a>.";
|
||||
"do_not_attach_note" = "Не прикреплять заметку";
|
||||
|
||||
/* Menus */
|
||||
|
||||
"edit_button" = "ред.";
|
||||
|
|
Loading…
Reference in a new issue