From 10729d82949753a5f9de809b4b2f4540bd7c0bff Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 30 Jul 2023 20:03:27 +0300 Subject: [PATCH 01/34] Wall: add early suggestions --- ServiceAPI/Wall.php | 57 ++++++++++++ VKAPI/Handlers/Wall.php | 51 ++++++++++- Web/Models/Entities/Club.php | 17 ++++ .../PostAcceptedNotification.php | 13 +++ Web/Models/Entities/Post.php | 5 ++ Web/Models/Repositories/Posts.php | 63 +++++++++++-- Web/Presenters/GroupPresenter.php | 78 +++++++++++++++- Web/Presenters/WallPresenter.php | 16 +++- Web/Presenters/templates/Group/Edit.xml | 7 +- Web/Presenters/templates/Group/Suggested.xml | 26 ++++++ Web/Presenters/templates/Group/View.xml | 12 +++ .../components/notifications/6/_14_5_.xml | 7 ++ .../components/post/microblogpost.xml | 8 +- Web/routes.yml | 4 + Web/static/css/main.css | 18 ++++ Web/static/js/al_wall.js | 90 ++++++++++++++++++- install/sqls/00039-suggest-posts.sql | 1 + locales/en.strings | 41 ++++++++- locales/ru.strings | 42 ++++++++- 19 files changed, 530 insertions(+), 26 deletions(-) create mode 100644 Web/Models/Entities/Notifications/PostAcceptedNotification.php create mode 100644 Web/Presenters/templates/Group/Suggested.xml create mode 100644 Web/Presenters/templates/components/notifications/6/_14_5_.xml create mode 100644 install/sqls/00039-suggest-posts.sql diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 5677f7ba5..73eeee36f 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -2,6 +2,7 @@ namespace openvk\ServiceAPI; use openvk\Web\Models\Entities\Post; use openvk\Web\Models\Entities\User; +use openvk\Web\Models\Entities\Notifications\{PostAcceptedNotification}; use openvk\Web\Models\Repositories\{Posts, Notes}; class Wall implements Handler @@ -95,4 +96,60 @@ function getMyNotes(callable $resolve, callable $reject) $resolve($arr); } + + function declinePost(int $id, callable $resolve, callable $reject) + { + $post = $this->posts->get($id); + if(!$post || $post->isDeleted()) + $reject(11, "No post with id=$id"); + + if($post->getSuggestionType() == 0) + $reject(19, "Post is not suggested"); + + if($post->getSuggestionType() == 2) + $reject(10, "Post is already declined"); + + if(!$post->canBePinnedBy($this->user)) + $reject(22, "Access to post denied :)"); + + $post->setSuggested(2); + $post->save(); + + $resolve($this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())); + } + + function acceptPost(int $id, bool $sign, string $content, callable $resolve, callable $reject) + { + $post = $this->posts->get($id); + if(!$post || $post->isDeleted()) + $reject(11, "No post with id=$id"); + + if($post->getSuggestionType() == 0) + $reject(19, "Post is not suggested"); + + if($post->getSuggestionType() == 2) + $reject(10, "Post is declined"); + + if(!$post->canBePinnedBy($this->user)) + $reject(22, "Access to post denied :)"); + + $author = $post->getOwner(); + $flags = 0; + $flags |= 0b10000000; + + if($sign) { + $flags |= 0b01000000; + } + + $post->setSuggested(0); + $post->setCreated(time()); + $post->setFlags($flags); + $post->setContent($content); + + $post->save(); + + (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + + $resolve(["id" => $post->getPrettyId(), "new_count" => $this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())]); + } } diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index d52dfce1f..dfe33c24e 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -18,7 +18,7 @@ final class Wall extends VKAPIRequestHandler { - function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 30, int $extended = 0): object + function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 30, int $extended = 0, string $filter = "all"): object { $this->requireUser(); @@ -27,7 +27,7 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 $items = []; $profiles = []; $groups = []; - $cnt = $posts->getPostCountOnUserWall($owner_id); + $cnt = 0; if ($owner_id > 0) $wallOnwer = (new UsersRepo)->get($owner_id); @@ -41,7 +41,43 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 if(!$wallOnwer) $this->fail(15, "Access denied: wall is disabled"); // Don't search for logic here pls - foreach($posts->getPostsFromUsersWall($owner_id, 1, $count, $offset) as $post) { + $iteratorv; + + switch($filter) { + case "all": + $iteratorv = $posts->getPostsFromUsersWall($owner_id, 1, $count, $offset); + $cnt = $posts->getPostCountOnUserWall($owner_id); + break; + case "owner": + $this->fail(66666, "Not implemented :("); + break; + case "others": + $this->fail(66666, "Not implemented :("); + break; + case "postponed": + $this->fail(66666, "Otlojka is not implemented :)"); + break; + # В апи, походу, нету метода, который бы публиковал запись из предложки + case "suggests": + if($owner_id < 0) { + if($wallOnwer->canBeModifiedBy($this->getUser())) { + $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); + $cnt = $posts->getSuggestedPostsCount($owner_id * -1); + } else { + $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); + $cnt = $posts->getSuggestedPostsCount($owner_id * -1); + } + } else { + $this->fail(528, "Suggested posts avaiable only at groups"); + } + + break; + default: + $this->fail(254, "Invalid filter"); + break; + } + + foreach($iteratorv as $post) { $from_id = get_class($post->getOwner()) == "openvk\Web\Models\Entities\Club" ? $post->getOwner()->getId() * (-1) : $post->getOwner()->getId(); $attachments = []; @@ -428,6 +464,11 @@ function post(string $owner_id, string $message = "", int $from_group = 0, int $ $post->setContent($message); $post->setFlags($flags); $post->setApi_Source_Name($this->getPlatform()); + + if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2) { + $post->setSuggested(1); + } + $post->save(); } catch(\LogicException $ex) { $this->fail(100, "One of the parameters specified was missing or invalid"); @@ -494,6 +535,10 @@ function post(string $owner_id, string $message = "", int $from_group = 0, int $ 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) { + return (object)["post_id" => "on_view"]; + } + return (object)["post_id" => $post->getVirtualId()]; } diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 15c458a95..722233b76 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -23,6 +23,10 @@ class Club extends RowModel const NOT_RELATED = 0; const SUBSCRIBED = 1; const REQUEST_SENT = 2; + + const WALL_CLOSED = 0; + const WALL_OPEN = 1; + const WALL_LIMITED = 2; function getId(): int { @@ -45,6 +49,11 @@ function getAvatarUrl(string $size = "miniscule"): string return is_null($avPhoto) ? "$serverUrl/assets/packages/static/openvk/img/camera_200.png" : $avPhoto->getURLBySizeId($size); } + + function getWallType(): int + { + return $this->getRecord()->wall; + } function getAvatarLink(): string { @@ -182,6 +191,14 @@ function setShortCode(?string $code = NULL): ?bool $this->stateChanges("shortcode", $code); return true; } + + function setWall(int $type) + { + if($type > 3 || $type < 0) + throw new \LogicException("Invalid wall"); + + $this->stateChanges("wall", $type); + } function isSubscriptionAccepted(User $user): bool { diff --git a/Web/Models/Entities/Notifications/PostAcceptedNotification.php b/Web/Models/Entities/Notifications/PostAcceptedNotification.php new file mode 100644 index 000000000..bb99d34e7 --- /dev/null +++ b/Web/Models/Entities/Notifications/PostAcceptedNotification.php @@ -0,0 +1,13 @@ +unwire(); $this->save(); } + + function getSuggestionType() + { + return $this->getRecord()->suggested; + } use Traits\TRichText; } diff --git a/Web/Models/Repositories/Posts.php b/Web/Models/Repositories/Posts.php index c354f1525..1dd2ca273 100644 --- a/Web/Models/Repositories/Posts.php +++ b/Web/Models/Repositories/Posts.php @@ -58,9 +58,10 @@ function getPostsFromUsersWall(int $user, int $page = 1, ?int $perPage = NULL, ? } $sel = $this->posts->where([ - "wall" => $user, - "pinned" => false, - "deleted" => false, + "wall" => $user, + "pinned" => false, + "deleted" => false, + "suggested" => 0, ])->order("created DESC")->limit($perPage, $offset); foreach($sel as $post) @@ -74,6 +75,7 @@ function getPostsByHashtag(string $hashtag, int $page = 1, ?int $perPage = NULL) ->where("MATCH (content) AGAINST (? IN BOOLEAN MODE)", "+$hashtag") ->where("deleted", 0) ->order("created DESC") + ->where("suggested", 0) ->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); foreach($sel as $post) @@ -85,14 +87,22 @@ function getPostCountByHashtag(string $hashtag): int $hashtag = "#$hashtag"; $sel = $this->posts ->where("content LIKE ?", "%$hashtag%") - ->where("deleted", 0); + ->where("deleted", 0) + ->where("suggested", 0); return sizeof($sel); } - function getPostById(int $wall, int $post): ?Post + function getPostById(int $wall, int $post, bool $forceSuggestion = false): ?Post { - $post = $this->posts->where(['wall' => $wall, 'virtual_id' => $post])->fetch(); + $post = $this->posts->where(['wall' => $wall, 'virtual_id' => $post]); + + if(!$forceSuggestion) { + $post->where("suggested", 0); + } + + $post = $post->fetch(); + if(!is_null($post)) return new Post($post); else @@ -112,7 +122,7 @@ function find(string $query = "", array $pars = [], string $sort = "id"): Util\E else $paramValue != NULL ? $notNullParams+=["$paramName" => "$paramValue"] : NULL; - $result = $this->posts->where("content LIKE ?", $query)->where("deleted", 0); + $result = $this->posts->where("content LIKE ?", $query)->where("deleted", 0)->where("suggested", 0); $nnparamsCount = sizeof($notNullParams); if($nnparamsCount > 0) { @@ -134,7 +144,44 @@ function find(string $query = "", array $pars = [], string $sort = "id"): Util\E function getPostCountOnUserWall(int $user): int { - return sizeof($this->posts->where(["wall" => $user, "deleted" => 0])); + return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])); + } + + function getSuggestedPosts(int $club, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + { + $sel = $this->posts + ->where("deleted", 0) + ->where("wall", $club * -1) + ->order("created DESC") + ->where("suggested", 1) + ->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); + + foreach($sel as $post) + yield new Post($post); + } + + function getSuggestedPostsCount(int $club) + { + return sizeof($this->posts->where(["wall" => $club * -1, "deleted" => 0, "suggested" => 1])); + } + + function getSuggestedPostsByUser(int $club, int $user, int $page = 1, ?int $perPage = NULL): \Traversable + { + $sel = $this->posts + ->where("deleted", 0) + ->where("wall", $club * -1) + ->where("owner", $user) + ->order("created DESC") + ->where("suggested", 1) + ->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); + + foreach($sel as $post) + yield new Post($post); + } + + function getSuggestedPostsCountByUser(int $club, int $user): int + { + return sizeof($this->posts->where(["wall" => $club * -1, "deleted" => 0, "suggested" => 1, "owner" => $user])); } function getCount(): int diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 4f671df35..822582b7a 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -3,7 +3,7 @@ use openvk\Web\Models\Entities\{Club, Photo, Post}; use Nette\InvalidStateException; use openvk\Web\Models\Entities\Notifications\ClubModeratorNotification; -use openvk\Web\Models\Repositories\{Clubs, Users, Albums, Managers, Topics}; +use openvk\Web\Models\Repositories\{Posts, Clubs, Users, Albums, Managers, Topics}; use Chandler\Security\Authenticator; final class GroupPresenter extends OpenVKPresenter @@ -29,6 +29,14 @@ function renderView(int $id): void $this->template->topics = (new Topics)->getLastTopics($club, 3); $this->template->topicsCount = (new Topics)->getClubTopicsCount($club); + if(!is_null($this->user->identity) && !$club->canBeModifiedBy($this->user->identity) && $club->getWallType() == 2) { + $this->template->suggestedPostsCountByUser = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); + } + + if(!is_null($this->user->identity) && $club->canBeModifiedBy($this->user->identity) && $club->getWallType() == 2) { + $this->template->suggestedPostsCountByEveryone = (new Posts)->getSuggestedPostsCount($club->getId()); + } + $this->template->club = $club; } } @@ -192,7 +200,7 @@ function renderEdit(int $id): void $this->willExecuteWriteAction(); $club = $this->clubs->get($id); - if(!$club || !$club->canBeModifiedBy($this->user->identity)) + if(!$club || !$club->canBeModifiedBy($this->user->identity) || $club->isDeleted()) $this->notFound(); else $this->template->club = $club; @@ -396,4 +404,68 @@ function renderChangeOwner(int $id, int $newOwnerId): void $this->flashFail("succ", tr("information_-1"), tr("group_owner_setted", $newOwner->getCanonicalName(), $club->getName())); } -} + + function renderSuggestedThisUser(int $id) + { + $this->assertUserLoggedIn(); + + $club = $this->clubs->get($id); + if(!$club || method_exists($club, "isDeleted") && $club->isDeleted()) + $this->notFound(); + else + $this->template->club = $club; + + if($club->getWallType() == 1) { + $this->flash("err", tr("error_suggestions"), tr("error_suggestions_closed")); + $this->redirect("/club".$club->getId()); + } + + if($club->getWallType() == 0) { + $this->flash("err", tr("error_suggestions"), tr("error_suggestions_open")); + $this->redirect("/club".$club->getId()); + } + + if($club->canBeModifiedBy($this->user->identity)) { + $this->flash("err", tr("error_suggestions"), "No sense"); + $this->redirect("/club".$club->getId()); + } + + $this->template->posts = (new Posts)->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1)); + $this->template->count = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); + $this->template->type = "my"; + $this->template->page = (int) ($this->queryParam("p") ?? 1); + $this->template->_template = "Group/Suggested.xml"; + } + + function renderSuggestedAll(int $id) + { + $this->assertUserLoggedIn(); + + $club = $this->clubs->get($id); + if(!$club || method_exists($club, "isDeleted") && $club->isDeleted()) + $this->notFound(); + else + $this->template->club = $club; + + if($club->getWallType() == 1) { + $this->flash("err", tr("error_suggestions"), tr("error_suggestions_closed")); + $this->redirect("/club".$club->getId()); + } + + if($club->getWallType() == 0) { + $this->flash("err", tr("error_suggestions"), tr("error_suggestions_open")); + $this->redirect("/club".$club->getId()); + } + + if(!$club->canBeModifiedBy($this->user->identity)) { + $this->flash("err", tr("error_suggestions"), tr("error_suggestions_access")); + $this->redirect("/club".$club->getId()); + } + + $this->template->posts = (new Posts)->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1)); + $this->template->count = (new Posts)->getSuggestedPostsCount($club->getId()); + $this->template->type = "everyone"; + $this->template->page = (int) ($this->queryParam("p") ?? 1); + $this->template->_template = "Group/Suggested.xml"; + } +} \ No newline at end of file diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 727101ffe..c135c2985 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -148,6 +148,7 @@ function renderFeed(): void ->select("id") ->where("wall IN (?)", $ids) ->where("deleted", 0) + ->where("suggested", 0) ->order("created DESC"); $this->template->paginatorConf = (object) [ "count" => sizeof($posts), @@ -167,7 +168,7 @@ function renderGlobalFeed(): void $page = (int) ($_GET["p"] ?? 1); $pPage = min((int) ($_GET["posts"] ?? OPENVK_DEFAULT_PER_PAGE), 50); - $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND `posts`.`deleted` = 0"; + $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0"; if($this->user->identity->getNsfwTolerance() === User::NSFW_INTOLERANT) $queryBase .= " AND `nsfw` = 0"; @@ -305,6 +306,11 @@ function renderMakePost(int $wall): void $post->setAnonymous($anon); $post->setFlags($flags); $post->setNsfw($this->postParam("nsfw") === "on"); + + if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { + $post->setSuggested(1); + } + $post->save(); } catch (\LengthException $ex) { $this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_too_big")); @@ -334,7 +340,11 @@ function renderMakePost(int $wall): void if($mentionee instanceof User) (new MentionNotification($mentionee, $post, $post->getOwner(), strip_tags($post->getText())))->emit(); - $this->redirect($wallOwner->getURL()); + if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { + $this->redirect("/club".$wallOwner->getId()."/suggested"); + } else { + $this->redirect($wallOwner->getURL()); + } } function renderPost(int $wall, int $post_id): void @@ -436,7 +446,7 @@ function renderDelete(int $wall, int $post_id): void $this->assertUserLoggedIn(); $this->willExecuteWriteAction(); - $post = $this->posts->getPostById($wall, $post_id); + $post = $this->posts->getPostById($wall, $post_id, true); if(!$post) $this->notFound(); $user = $this->user->id; diff --git a/Web/Presenters/templates/Group/Edit.xml b/Web/Presenters/templates/Group/Edit.xml index 22f0b4902..6d3b013dc 100644 --- a/Web/Presenters/templates/Group/Edit.xml +++ b/Web/Presenters/templates/Group/Edit.xml @@ -77,7 +77,12 @@ {_wall}: - {_group_allow_post_for_everyone}
+ + {_group_hide_from_global_feed} diff --git a/Web/Presenters/templates/Group/Suggested.xml b/Web/Presenters/templates/Group/Suggested.xml new file mode 100644 index 000000000..bd6649d97 --- /dev/null +++ b/Web/Presenters/templates/Group/Suggested.xml @@ -0,0 +1,26 @@ +{extends "../@layout.xml"} + +{block title}{_suggested} {$club->getCanonicalName()}{/block} + +{block header} + {$club->getName()} + » {if $type == "my"}{_suggested_posts_by_you}{else}{_suggested_posts_by_everyone}{/if} +{/block} + +{block content} + {if $count < 1} + {include "../components/error.xml", title => "", description => $type == "my" ? tr("no_suggested_posts_by_you") : tr("no_suggested_posts_by_people")} + {else} +

{if $type == "my"}{tr("x_suggested_posts_in_group_by_you", $count)}{else}{tr("x_suggested_posts_in_group", $count)}{/if}

+ {foreach $posts as $post} + {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true} + {/foreach} + {/if} + {include "../components/paginator.xml", conf => (object) [ + "page" => $page, + "count" => $count, + "amount" => sizeof($posts), + "perPage" => OPENVK_DEFAULT_PER_PAGE, + "atBottom" => true, + ]} +{/block} diff --git a/Web/Presenters/templates/Group/View.xml b/Web/Presenters/templates/Group/View.xml index bf392a9f2..4a588c135 100644 --- a/Web/Presenters/templates/Group/View.xml +++ b/Web/Presenters/templates/Group/View.xml @@ -91,7 +91,19 @@ +
+ {tr("show_suggested_posts", $suggestedPostsCountByUser)} +
+ +
+ {tr("show_suggested_posts_everyone", $suggestedPostsCountByEveryone)} +
+ {presenter "openvk!Wall->wallEmbedded", -$club->getId()} + +
{var $avatarPhoto = $club->getAvatarPhoto()} diff --git a/Web/Presenters/templates/components/notifications/6/_14_5_.xml b/Web/Presenters/templates/components/notifications/6/_14_5_.xml new file mode 100644 index 000000000..ab77cb94a --- /dev/null +++ b/Web/Presenters/templates/components/notifications/6/_14_5_.xml @@ -0,0 +1,7 @@ +{var $club = $notification->getModel(1)} +{var $post = $notification->getModel(0)} + +{_group} +{$club->getName()} +{_nt_accepted_your_post} +{_nt_post_small}. \ No newline at end of file diff --git a/Web/Presenters/templates/components/post/microblogpost.xml b/Web/Presenters/templates/components/post/microblogpost.xml index 98a41d72f..b5060fcba 100644 --- a/Web/Presenters/templates/components/post/microblogpost.xml +++ b/Web/Presenters/templates/components/post/microblogpost.xml @@ -65,7 +65,7 @@
- {$post->getText()|noescape} + {$post->getText()|noescape}
@@ -88,7 +88,7 @@
- {$post->getPublicationTime()} + {$post->getPublicationTime()} @@ -124,6 +124,10 @@ {include "../textArea.xml", route => $commentsURL, postOpts => false, graffiti => (bool) ovkGetQuirk("comments.allow-graffiti"), post => $post, club => $club}
+
+ + +
diff --git a/Web/routes.yml b/Web/routes.yml index d1a0e7aef..2dbc8a2b5 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -201,6 +201,10 @@ routes: handler: "Group->admin" - url: "/club{num}/setAdmin" handler: "Group->modifyAdmin" + - url: "/club{num}/suggested" + handler: "Group->suggestedThisUser" + - url: "/club{num}/suggested/all" + handler: "Group->suggestedAll" - url: "/groups{num}" handler: "User->groups" - url: "/groups_pin" diff --git a/Web/static/css/main.css b/Web/static/css/main.css index bbbe4d285..22aa420db 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2695,4 +2695,22 @@ body.article .floating_sidebar, body.article .page_content { position: absolute; right: 22px; font-size: 12px; +} + +.sugglist { + padding-bottom: 5px; + padding-top: 5px; + margin-bottom: -5px; + padding-left: 9px; + border-top: 1px solid gray; + background-color: #e6e6e6; + margin-top: 5px; +} + +.sugglist a { + color: #626262; +} + +.suggestionControls { + text-align: center; } \ No newline at end of file diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index bb349c145..f60a30619 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -192,7 +192,7 @@ tippy(".client_app", { function addNote(textareaId, nid) { if(nid > 0) { - note.value = nid + document.getElementById("note").value = nid let noteObj = document.querySelector("#nd"+nid) let nortd = document.querySelector("#post-buttons"+textareaId+" .post-has-note"); @@ -200,7 +200,7 @@ function addNote(textareaId, nid) nortd.innerHTML = `${tr("note")} ${escapeHtml(noteObj.dataset.name)}` } else { - note.value = "none" + document.getElementById("note").value = "none" let nortd = document.querySelector("#post-buttons"+textareaId+" .post-has-note"); nortd.style.display = "none" @@ -227,7 +227,7 @@ async function attachNote(id) ${tr("select_or_create_new")}
` - if(note.value != "none") { + if(document.getElementById("note").value != "none") { body += `
${tr("do_not_attach_note")} @@ -262,4 +262,86 @@ async function showArticle(note_id) { u("#articleText").html(`

${note.title}

` + note.html); u("body").removeClass("dimmed"); u("body").addClass("article"); -} \ No newline at end of file +} + +$(document).on("click", "#publish_post", async (e) => { + let id = Number(e.currentTarget.dataset.id) + let post; + let body = ` + + + ` + + MessageBox(tr("publishing_suggested_post"), body, [tr("publish"), tr("cancel")], [(async () => { + let id = Number(e.currentTarget.dataset.id) + let post; + + try { + post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value) + } catch(ex) { + switch(ex.code) { + case 11: + MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); + break; + case 19: + MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); + break; + case 10: + MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); + break; + case 22: + MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); + break; + default: + MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); + break; + } + + return 0; + } + + NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); + document.getElementById("cound").innerHTML = tr("x_suggested_posts_in_group", post.new_count) + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + }), Function.noop]); + + document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML + document.querySelector(".ovk-diag-body").style.padding = "9px"; +}) + +$(document).on("click", "#decline_post", async (e) => { + let id = Number(e.currentTarget.dataset.id) + let post; + + try { + e.currentTarget.parentNode.parentNode.insertAdjacentHTML("afterbegin", ``) + post = await API.Wall.declinePost(id) + } catch(ex) { + switch(ex.code) { + case 11: + MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); + break; + case 19: + MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); + break; + case 10: + MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); + break; + case 22: + MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); + break; + default: + MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); + break; + } + + return 0; + } finally { + u("#deleteMe").remove() + } + + // а хули + NewNotification(tr("suggestion_succefully_declined"), "", null); + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + document.getElementById("cound").innerHTML = tr("x_suggested_posts_in_group", post) +}) \ No newline at end of file diff --git a/install/sqls/00039-suggest-posts.sql b/install/sqls/00039-suggest-posts.sql new file mode 100644 index 000000000..321c2a6a9 --- /dev/null +++ b/install/sqls/00039-suggest-posts.sql @@ -0,0 +1 @@ +ALTER TABLE `posts` ADD `suggested` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `deleted`; \ No newline at end of file diff --git a/locales/en.strings b/locales/en.strings index 4aaa4483a..020076a95 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -260,6 +260,7 @@ /* Group */ +"group" = "Group"; "name_group" = "Name"; "subscribe" = "Subscribe"; "unsubscribe" = "Unsubscribe"; @@ -297,8 +298,38 @@ "set_comment" = "Set comment"; "hidden_yes" = "Hidden: Yes"; "hidden_no" = "Hidden: No"; -"group_allow_post_for_everyone" = "Allow posting for everyone"; +"group_allow_post_for_everyone" = "Open"; +"group_limited_post" = "Suggestions"; +"group_closed_post" = "Closed"; +"suggest_new" = "Suggest post"; +"show_suggested_posts" = "$1 suggested posts by you"; +"show_suggested_posts_everyone" = "$1 suggested posts"; "group_hide_from_global_feed" = "Don't display posts in the global feed"; +"suggested_posts_by_you" = "Suggested posts by you"; +"suggested_posts_by_everyone" = "Suggested posts"; +"suggested" = "Suggested"; +"suggested_posts_everyone" = "Suggested by users posts"; +"no_suggested_posts_by_you" = "You haven't suggested posts to this group yet."; +"no_suggested_posts_by_people" = "No posts have been suggested to this group yet."; + +"publish_suggested" = "Accept"; +"decline_suggested" = "Decline"; + +"publishing_suggested_post" = "Publishing suggested post"; +"x_suggested_posts_in_group" = "This group has $1 suggested posts"; +"x_suggested_posts_in_group_by_you" = "You suggested $1 posts to this group"; + +"suggestion_succefully_published" = "Post successfully published"; +"suggestion_succefully_declined" = "Post successfully declined"; +"suggestion_press_to_go" = "Click to show him"; + +"error_declining_invalid_post" = "Error when declining post: post does not exists"; +"error_declining_not_suggested_post" = "Error when declining post: post is not suggested"; +"error_declining_declined_post" = "Error when declining post: post is already declined"; + +"error_accepting_invalid_post" = "Error when accepting post: post does not exists"; +"error_accepting_not_suggested_post" = "Error when accepting post: post is not suggested"; +"error_accepting_declined_post" = "Error when accepting post: cant accept declined post"; "statistics" = "Statistics"; "group_administrators_list" = "Admins list"; "group_display_only_creator" = "Display only group creator"; @@ -331,6 +362,11 @@ "search_by_groups" = "Search by groups"; "search_group_desc" = "Here you can browse through the existing groups and choose a group to suit your needs..."; +"error_suggestions" = "Error accessing to suggestions"; +"error_suggestions_closed" = "This group has closed wall."; +"error_suggestions_open" = "This group has open wall."; +"error_suggestions_access" = "Only group's administrators can view all suggested posts."; + /* Albums */ "create" = "Create"; @@ -675,6 +711,7 @@ "nt_shared_yours" = "shared your"; "nt_commented_yours" = "commented"; "nt_written_on_your_wall" = "wrote on your wall"; +"nt_accepted_your_post" = "accepted your suggested"; "nt_made_you_admin" = "appointed you in the community"; "nt_from" = "from"; @@ -694,6 +731,8 @@ "nt_mention_in_note" = "in discussion of this note"; "nt_mention_in_topic" = "in the discussion"; +"nt_post_small" = "post"; + /* Time */ "time_at_sp" = " at "; diff --git a/locales/ru.strings b/locales/ru.strings index 6faa5e2e2..a4f06e47d 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -245,6 +245,7 @@ /* Group */ +"group" = "Сообщество"; "name_group" = "Название"; "subscribe" = "Подписаться"; "unsubscribe" = "Отписаться"; @@ -281,8 +282,40 @@ "set_comment" = "Изменить комментарий"; "hidden_yes" = "Скрыт: Да"; "hidden_no" = "Скрыт: Нет"; -"group_allow_post_for_everyone" = "Разрешить публиковать записи всем"; + +"group_allow_post_for_everyone" = "Открытая"; +"group_limited_post" = "Предложка"; +"group_closed_post" = "Закрытая"; +"suggest_new" = "Предложить новость"; +"show_suggested_posts" = "$1 предложенных вами записей"; +"show_suggested_posts_everyone" = "$1 предложенных записей"; "group_hide_from_global_feed" = "Не отображать публикации в глобальной ленте"; +"suggested_posts_by_you" = "Предложенные вами записи"; +"suggested_posts_by_everyone" = "Предложенные записи"; +"suggested" = "Предложено"; +"suggested_posts_everyone" = "Предложенные пользователями записи"; +"no_suggested_posts_by_you" = "Вы ещё не предлагали записей в эту группу."; +"no_suggested_posts_by_people" = "В эту группу ещё не предлагали записей."; + +"publish_suggested" = "Опубликовать запись"; +"decline_suggested" = "Отклонить"; + +"publishing_suggested_post" = "Публикация предложенной записи"; +"x_suggested_posts_in_group" = "В эту группу предложили $1 записей"; +"x_suggested_posts_in_group_by_you" = "Вы предложили в эту группу $1 записей"; + +"suggestion_succefully_published" = "Запись успешно опубликована"; +"suggestion_succefully_declined" = "Запись успешно отклонена"; +"suggestion_press_to_go" = "Нажмите, чтобы перейти к ней"; + +"error_declining_invalid_post" = "Не удалость отклонить пост: поста не существует"; +"error_declining_not_suggested_post" = "Не удалость отклонить пост: пост не из предложки"; +"error_declining_declined_post" = "Не удалость отклонить пост: пост уже отклонён"; + +"error_accepting_invalid_post" = "Не удалость принять пост: поста не существует"; +"error_accepting_not_suggested_post" = "Не удалость принять пост: пост не из предложки"; +"error_accepting_declined_post" = "Не удалость принять пост: пост отклонён"; + "statistics" = "Статистика"; "group_administrators_list" = "Список админов"; "group_display_only_creator" = "Отображать только создателя группы"; @@ -315,6 +348,11 @@ "search_by_groups" = "Поиск по группам"; "search_group_desc" = "Здесь Вы можете просмотреть существующие группы и выбрать группу себе по вкусу..."; +"error_suggestions" = "Ошибка доступа к предложенным"; +"error_suggestions_closed" = "У этой группы закрытая стена."; +"error_suggestions_open" = "У этой группы открытая стена."; +"error_suggestions_access" = "Просматривать все предложенные записи могут только администраторы группы."; + /* Albums */ "create" = "Создать"; @@ -632,6 +670,7 @@ "nt_shared_yours" = "поделился(-ась) вашим"; "nt_commented_yours" = "оставил(а) комментарий под"; "nt_written_on_your_wall" = "написал(а) на вашей стене"; +"nt_accepted_your_post" = "опубликовало вашу предложенную"; "nt_made_you_admin" = "назначил(а) вас руководителем сообщества"; "nt_from" = "от"; "nt_yours_adjective" = "вашим"; @@ -649,6 +688,7 @@ "nt_mention_in_video" = "в обсуждении видеозаписи"; "nt_mention_in_note" = "в обсуждении заметки"; "nt_mention_in_topic" = "в обсуждении"; +"nt_post_small" = "запись"; /* Time */ From eff2b2bba19f0ec32bdf5c60df65090551793de3 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:44:49 +0300 Subject: [PATCH 02/34] Fix br --- Web/static/js/al_wall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index f60a30619..9eff0e15e 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -305,7 +305,7 @@ $(document).on("click", "#publish_post", async (e) => { e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" }), Function.noop]); - document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML + document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/
/g, '') document.querySelector(".ovk-diag-body").style.padding = "9px"; }) From 213f1e286c6db65a46b1daeec2fc169b7033c3f1 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:00:55 +0300 Subject: [PATCH 03/34] Fix empty posts --- ServiceAPI/Wall.php | 9 ++++++--- VKAPI/Handlers/Wall.php | 3 ++- Web/Presenters/GroupPresenter.php | 9 +++++++-- Web/static/js/al_wall.js | 3 +-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 73eeee36f..62b1fe2cd 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -110,7 +110,7 @@ function declinePost(int $id, callable $resolve, callable $reject) $reject(10, "Post is already declined"); if(!$post->canBePinnedBy($this->user)) - $reject(22, "Access to post denied :)"); + $reject(22, "Access to post denied"); $post->setSuggested(2); $post->save(); @@ -131,7 +131,7 @@ function acceptPost(int $id, bool $sign, string $content, callable $resolve, cal $reject(10, "Post is declined"); if(!$post->canBePinnedBy($this->user)) - $reject(22, "Access to post denied :)"); + $reject(22, "Access to post denied"); $author = $post->getOwner(); $flags = 0; @@ -144,7 +144,10 @@ function acceptPost(int $id, bool $sign, string $content, callable $resolve, cal $post->setSuggested(0); $post->setCreated(time()); $post->setFlags($flags); - $post->setContent($content); + + if(mb_strlen($content) > 0) { + $post->setContent($content); + } $post->save(); diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index dfe33c24e..38033ea7e 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -57,7 +57,8 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 case "postponed": $this->fail(66666, "Otlojka is not implemented :)"); break; - # В апи, походу, нету метода, который бы публиковал запись из предложки + # В вкапи, походу, нету метода, который бы публиковал запись из предложки. + # Либо он закрыт для неофициальных клиентов, как gifts.send case "suggests": if($owner_id < 0) { if($wallOnwer->canBeModifiedBy($this->getUser())) { diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 822582b7a..3ead10b4a 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -200,7 +200,7 @@ function renderEdit(int $id): void $this->willExecuteWriteAction(); $club = $this->clubs->get($id); - if(!$club || !$club->canBeModifiedBy($this->user->identity) || $club->isDeleted()) + if(!$club || !$club->canBeModifiedBy($this->user->identity)) $this->notFound(); else $this->template->club = $club; @@ -211,7 +211,12 @@ function renderEdit(int $id): void $club->setName(empty($this->postParam("name")) ? $club->getName() : $this->postParam("name")); $club->setAbout(empty($this->postParam("about")) ? NULL : $this->postParam("about")); - $club->setWall(empty($this->postParam("wall")) ? 0 : 1); + try { + $club->setWall(empty($this->postParam("wall")) ? 0 : (int)$this->postParam("wall")); + } catch(\Exception $e) { + $this->flashFail("err", "Fuck you", ""); + } + $club->setAdministrators_List_Display(empty($this->postParam("administrators_list_display")) ? 0 : $this->postParam("administrators_list_display")); $club->setEveryone_Can_Create_Topics(empty($this->postParam("everyone_can_create_topics")) ? 0 : 1); $club->setDisplay_Topics_Above_Wall(empty($this->postParam("display_topics_above_wall")) ? 0 : 1); diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 9eff0e15e..51683bd8f 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -339,8 +339,7 @@ $(document).on("click", "#decline_post", async (e) => { } finally { u("#deleteMe").remove() } - - // а хули + NewNotification(tr("suggestion_succefully_declined"), "", null); e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" document.getElementById("cound").innerHTML = tr("x_suggested_posts_in_group", post) From 3809b82cecc17f231d27ff9bc3461f8bb241ef7d Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:48:27 +0300 Subject: [PATCH 04/34] fck --- VKAPI/Handlers/Wall.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 38033ea7e..3b93be2fe 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -65,8 +65,8 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); $cnt = $posts->getSuggestedPostsCount($owner_id * -1); } else { - $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); - $cnt = $posts->getSuggestedPostsCount($owner_id * -1); + $iteratorv = $posts->getSuggestedPostsByUser($owner_id * -1, $this->getUser()->getId(), 1, $count, $offset); + $cnt = $posts->getSuggestedPostsCountByUser($owner_id * -1, $this->getUser()->getId()); } } else { $this->fail(528, "Suggested posts avaiable only at groups"); From cd546621b351c705ad945f447836ce5e6bbb2fef Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:20:54 +0300 Subject: [PATCH 05/34] Add offset for api --- Web/Models/Repositories/Posts.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Web/Models/Repositories/Posts.php b/Web/Models/Repositories/Posts.php index 1dd2ca273..4cde11a59 100644 --- a/Web/Models/Repositories/Posts.php +++ b/Web/Models/Repositories/Posts.php @@ -149,12 +149,15 @@ function getPostCountOnUserWall(int $user): int function getSuggestedPosts(int $club, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable { + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + $offset ??= $perPage * ($page - 1); + $sel = $this->posts ->where("deleted", 0) ->where("wall", $club * -1) ->order("created DESC") ->where("suggested", 1) - ->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); + ->limit($perPage, $offset); foreach($sel as $post) yield new Post($post); @@ -165,15 +168,18 @@ function getSuggestedPostsCount(int $club) return sizeof($this->posts->where(["wall" => $club * -1, "deleted" => 0, "suggested" => 1])); } - function getSuggestedPostsByUser(int $club, int $user, int $page = 1, ?int $perPage = NULL): \Traversable + function getSuggestedPostsByUser(int $club, int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable { + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + $offset ??= $perPage * ($page - 1); + $sel = $this->posts ->where("deleted", 0) ->where("wall", $club * -1) ->where("owner", $user) ->order("created DESC") ->where("suggested", 1) - ->page($page, $perPage ?? OPENVK_DEFAULT_PER_PAGE); + ->limit($perPage, $offset); foreach($sel as $post) yield new Post($post); From 61205f64d9cf29993f564508f9206cc56ef97850 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 31 Jul 2023 19:14:24 +0300 Subject: [PATCH 06/34] Add notifications of new suggestion posts --- VKAPI/Handlers/Wall.php | 14 +++++++++++++- .../NewSuggestedPostsNotification.php | 13 +++++++++++++ Web/Presenters/WallPresenter.php | 16 +++++++++++++++- .../components/notifications/7/_18_5_.xml | 5 +++++ locales/en.strings | 2 ++ locales/ru.strings | 2 ++ 6 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 Web/Models/Entities/Notifications/NewSuggestedPostsNotification.php create mode 100644 Web/Presenters/templates/components/notifications/7/_18_5_.xml diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 3b93be2fe..74eacb8ec 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -1,7 +1,7 @@ user->identity))->emit(); if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2) { + $suggsCount = (new PostsRepo)->getSuggestedPostsCount($wallOwner->getId()); + + if($suggsCount % 10 == 0) { + $managers = $wallOwner->getManagers(); + $owner = $wallOwner->getOwner(); + (new NewSuggestedPostsNotification($owner, $wallOwner))->emit(); + + foreach($managers as $manager) { + (new NewSuggestedPostsNotification($manager->getUser(), $wallOwner))->emit(); + } + } + return (object)["post_id" => "on_view"]; } diff --git a/Web/Models/Entities/Notifications/NewSuggestedPostsNotification.php b/Web/Models/Entities/Notifications/NewSuggestedPostsNotification.php new file mode 100644 index 000000000..e1795b08a --- /dev/null +++ b/Web/Models/Entities/Notifications/NewSuggestedPostsNotification.php @@ -0,0 +1,13 @@ +getOwner(), strip_tags($post->getText())))->emit(); if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { + $suggsCount = $this->posts->getSuggestedPostsCount($wallOwner->getId()); + + # Возможно, это заебёт админов групп, но так они хотя бы про паблик вспомнят + # Мб рандома добавить? + if($suggsCount % 10 == 0) { + $managers = $wallOwner->getManagers(); + $owner = $wallOwner->getOwner(); + (new NewSuggestedPostsNotification($owner, $wallOwner))->emit(); + + foreach($managers as $manager) { + (new NewSuggestedPostsNotification($manager->getUser(), $wallOwner))->emit(); + } + } + $this->redirect("/club".$wallOwner->getId()."/suggested"); } else { $this->redirect($wallOwner->getURL()); diff --git a/Web/Presenters/templates/components/notifications/7/_18_5_.xml b/Web/Presenters/templates/components/notifications/7/_18_5_.xml new file mode 100644 index 000000000..4c012edd6 --- /dev/null +++ b/Web/Presenters/templates/components/notifications/7/_18_5_.xml @@ -0,0 +1,5 @@ +{var $club = $notification->getModel(1)} + +{_nt_in_club} +{$club->getName()} +{_nt_new_suggested_posts} \ No newline at end of file diff --git a/locales/en.strings b/locales/en.strings index 020076a95..e7f616aca 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -712,6 +712,8 @@ "nt_commented_yours" = "commented"; "nt_written_on_your_wall" = "wrote on your wall"; "nt_accepted_your_post" = "accepted your suggested"; +"nt_in_club" = "In group"; +"nt_new_suggested_posts" = "new posts in suggestions"; "nt_made_you_admin" = "appointed you in the community"; "nt_from" = "from"; diff --git a/locales/ru.strings b/locales/ru.strings index a4f06e47d..47a769422 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -671,6 +671,8 @@ "nt_commented_yours" = "оставил(а) комментарий под"; "nt_written_on_your_wall" = "написал(а) на вашей стене"; "nt_accepted_your_post" = "опубликовало вашу предложенную"; +"nt_in_club" = "В сообществе"; +"nt_new_suggested_posts" = "новые записи в предложке"; "nt_made_you_admin" = "назначил(а) вас руководителем сообщества"; "nt_from" = "от"; "nt_yours_adjective" = "вашим"; From 9a20682e019764094dcb0b86b0791d39cc9e8503 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Tue, 1 Aug 2023 13:27:53 +0300 Subject: [PATCH 07/34] Fix mentions in suggested posts --- Web/Presenters/WallPresenter.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index f3f939f5e..d189013df 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -335,10 +335,15 @@ function renderMakePost(int $wall): void if($wall > 0) $excludeMentions[] = $wall; - $mentions = iterator_to_array($post->resolveMentions($excludeMentions)); - foreach($mentions as $mentionee) - if($mentionee instanceof User) - (new MentionNotification($mentionee, $post, $post->getOwner(), strip_tags($post->getText())))->emit(); + if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { + # Чтобы не было упоминаний из предложки + } else { + $mentions = iterator_to_array($post->resolveMentions($excludeMentions)); + + foreach($mentions as $mentionee) + if($mentionee instanceof User) + (new MentionNotification($mentionee, $post, $post->getOwner(), strip_tags($post->getText())))->emit(); + } if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { $suggsCount = $this->posts->getSuggestedPostsCount($wallOwner->getId()); From 1fcc372f18b51d3085a2624da93dd6314d5767da Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Wed, 2 Aug 2023 12:59:29 +0300 Subject: [PATCH 08/34] =?UTF-8?q?=F0=9F=A4=AE=F0=9F=A4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ServiceAPI/Wall.php | 1 + VKAPI/Handlers/Groups.php | 36 ++++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 62b1fe2cd..1b9bcabb6 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -113,6 +113,7 @@ function declinePost(int $id, callable $resolve, callable $reject) $reject(22, "Access to post denied"); $post->setSuggested(2); + $post->setDeleted(1); $post->save(); $resolve($this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())); diff --git a/VKAPI/Handlers/Groups.php b/VKAPI/Handlers/Groups.php index 3123a43f4..2937795a9 100644 --- a/VKAPI/Handlers/Groups.php +++ b/VKAPI/Handlers/Groups.php @@ -288,7 +288,7 @@ function edit( string $description = NULL, string $screen_name = NULL, string $website = NULL, - int $wall = NULL, + int $wall = -1, int $topics = NULL, int $adminlist = NULL, int $topicsAboveWall = NULL, @@ -303,17 +303,29 @@ function edit( if(!$club || !$club->canBeModifiedBy($this->getUser())) $this->fail(15, "You can't modify this group."); if(!empty($screen_name) && !$club->setShortcode($screen_name)) $this->fail(103, "Invalid shortcode."); - !is_null($title) ? $club->setName($title) : NULL; - !is_null($description) ? $club->setAbout($description) : NULL; - !is_null($screen_name) ? $club->setShortcode($screen_name) : NULL; - !is_null($website) ? $club->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website) : NULL; - !is_null($wall) ? $club->setWall($wall) : NULL; - !is_null($topics) ? $club->setEveryone_Can_Create_Topics($topics) : NULL; - !is_null($adminlist) ? $club->setAdministrators_List_Display($adminlist) : NULL; - !is_null($topicsAboveWall) ? $club->setDisplay_Topics_Above_Wall($topicsAboveWall) : NULL; - !is_null($hideFromGlobalFeed) ? $club->setHide_From_Global_Feed($hideFromGlobalFeed) : NULL; + !empty($title) ? $club->setName($title) : NULL; + !empty($description) ? $club->setAbout($description) : NULL; + !empty($screen_name) ? $club->setShortcode($screen_name) : NULL; + !empty($website) ? $club->setWebsite((!parse_url($website, PHP_URL_SCHEME) ? "https://" : "") . $website) : NULL; + + try { + $wall != -1 ? $club->setWall($wall) : NULL; + } catch(\Exception $e) { + $this->fail(50, "Invalid wall value"); + } - $club->save(); + !empty($topics) ? $club->setEveryone_Can_Create_Topics($topics) : NULL; + !empty($adminlist) ? $club->setAdministrators_List_Display($adminlist) : NULL; + !empty($topicsAboveWall) ? $club->setDisplay_Topics_Above_Wall($topicsAboveWall) : NULL; + !empty($hideFromGlobalFeed) ? $club->setHide_From_Global_Feed($hideFromGlobalFeed) : NULL; + + try { + $club->save(); + } catch(\TypeError $e) { + $this->fail(15, "Nothing changed"); + } catch(\Exception $e) { + $this->fail(18, "An unknown error occurred: maybe you set an incorrect value?"); + } return 1; } @@ -466,7 +478,7 @@ function getSettings(string $group_id) "title" => $club->getName(), "description" => $club->getDescription() != NULL ? $club->getDescription() : "", "address" => $club->getShortcode(), - "wall" => $club->canPost() == true ? 1 : 0, + "wall" => $club->getWallType(), # отличается от вкшных но да ладно "photos" => 1, "video" => 0, "audio" => 0, From 4ee9a0d4bf07327bb96340abfab624f0233c1bdf Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:54:20 +0300 Subject: [PATCH 09/34] Change regex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Теперь оно удаляет все теги а не только
--- Web/static/js/al_wall.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 51683bd8f..3f230a288 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -305,7 +305,7 @@ $(document).on("click", "#publish_post", async (e) => { e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" }), Function.noop]); - document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/
/g, '') + document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') document.querySelector(".ovk-diag-body").style.padding = "9px"; }) From 9543fb6c6b6a16d4851c1c72d96a2b4429427dda Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Fri, 4 Aug 2023 14:09:38 +0300 Subject: [PATCH 10/34] Add da koroche pohuy --- Web/Models/Entities/Club.php | 9 ++++++++- Web/Presenters/templates/@layout.xml | 11 ++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 722233b76..f5f64f23f 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -3,7 +3,7 @@ use openvk\Web\Util\DateTime; use openvk\Web\Models\RowModel; use openvk\Web\Models\Entities\{User, Manager}; -use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Managers}; +use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Managers, Posts}; use Nette\Database\Table\{ActiveRow, GroupedSelection}; use Chandler\Database\DatabaseConnection as DB; use Chandler\Security\User as ChandlerUser; @@ -308,6 +308,13 @@ function getFollowers(int $page = 1, int $perPage = 6, string $sort = "follower yield $rel; } } + + function getSuggestedPostsCount() + { + $count = (new Posts)->getSuggestedPostsCount($this->getId()); + + return $count; + } function getManagers(int $page = 1, bool $ignoreHidden = false): \Traversable { diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 1718c4990..5c006ea5a 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -214,7 +214,16 @@
From cb8dd4d12db93a54192e5bdefafb4aa15c7bfdee Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Fri, 4 Aug 2023 19:09:06 +0300 Subject: [PATCH 11/34] =?UTF-8?q?=D0=AD=D0=B4=D0=B4=20=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=20=D0=BC=D0=B5=D1=82=D1=85=D0=BE=D0=B4=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Методы нестандартные немного --- VKAPI/Handlers/Wall.php | 79 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 74eacb8ec..0f5fa2c3f 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -1,7 +1,7 @@ getWallType() != 2) + $this->fail(125, "Group's wall type is open or closed"); + if($wallOnwer->canBeModifiedBy($this->getUser())) { $iteratorv = $posts->getSuggestedPosts($owner_id * -1, 1, $count, $offset); $cnt = $posts->getSuggestedPostsCount($owner_id * -1); @@ -834,6 +837,80 @@ function deleteComment(int $comment_id) { return 1; } + # !!! Нестандартный метод + function acceptPost(int $club, int $post_id, string $new_message = "", bool $sign = true) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if($club < 0) { + $this->fail(62, "Club's id is negative"); + } + + $post = (new PostsRepo)->getPostById($club * -1, $post_id, true); + if(!$post || $post->isDeleted()) + $this->fail(32, "Invald post"); + + if($post->getSuggestionType() == 0) + $this->fail(20, "Post is not suggested"); + + if($post->getSuggestionType() == 2) + $this->fail(16, "Post is declined"); + + if(!$post->canBePinnedBy($this->getUser())) + $this->fail(51, "Access denied"); + + $author = $post->getOwner(); + $flags = 0; + $flags |= 0b10000000; + + if($sign) + $flags |= 0b01000000; + + $post->setSuggested(0); + $post->setCreated(time()); + $post->setFlags($flags); + + if(!empty($new_message) && iconv_strlen($new_message) > 0) + $post->setContent($new_message); + + $post->save(); + (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + + return 1; + } + + # !!! Нестандартный метод + function declinePost(int $club, int $post_id) + { + $this->requireUser(); + $this->willExecuteWriteAction(); + + if($club < 0) { + $this->fail(62, "Club's id is negative"); + } + + $post = (new PostsRepo)->getPostById($club * -1, $post_id, true); + + if(!$post || $post->isDeleted()) + $this->fail(32, "Invald post"); + + if($post->getSuggestionType() == 0) + $this->fail(20, "Post is not suggested"); + + if($post->getSuggestionType() == 2) + $this->fail(16, "Post is already declined"); + + if(!$post->canBePinnedBy($this->getUser())) + $this->fail(51, "Access denied"); + + $post->setSuggested(2); + $post->setDeleted(1); + $post->save(); + + return 1; + } + private function getApiPhoto($attachment) { return [ "type" => "photo", From c3ac279a25a022efeff71a06fd334881ead29bd8 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 6 Aug 2023 15:47:54 +0300 Subject: [PATCH 12/34] Pon --- Web/Presenters/GroupPresenter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 3ead10b4a..2db88baaf 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -415,7 +415,7 @@ function renderSuggestedThisUser(int $id) $this->assertUserLoggedIn(); $club = $this->clubs->get($id); - if(!$club || method_exists($club, "isDeleted") && $club->isDeleted()) + if(!$club) $this->notFound(); else $this->template->club = $club; @@ -447,7 +447,7 @@ function renderSuggestedAll(int $id) $this->assertUserLoggedIn(); $club = $this->clubs->get($id); - if(!$club || method_exists($club, "isDeleted") && $club->isDeleted()) + if(!$club) $this->notFound(); else $this->template->club = $club; From 5e67163af76cdf7e6db4d46774e51fbc05fc4625 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 6 Aug 2023 16:43:38 +0300 Subject: [PATCH 13/34] Add skloneniyia --- Web/Presenters/templates/Group/Suggested.xml | 2 +- Web/Presenters/templates/Group/View.xml | 4 +-- Web/static/js/al_wall.js | 4 +-- locales/en.strings | 28 +++++++++++++++++--- locales/ru.strings | 27 ++++++++++++++++--- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Web/Presenters/templates/Group/Suggested.xml b/Web/Presenters/templates/Group/Suggested.xml index bd6649d97..93ec70253 100644 --- a/Web/Presenters/templates/Group/Suggested.xml +++ b/Web/Presenters/templates/Group/Suggested.xml @@ -11,7 +11,7 @@ {if $count < 1} {include "../components/error.xml", title => "", description => $type == "my" ? tr("no_suggested_posts_by_you") : tr("no_suggested_posts_by_people")} {else} -

{if $type == "my"}{tr("x_suggested_posts_in_group_by_you", $count)}{else}{tr("x_suggested_posts_in_group", $count)}{/if}

+

{if $type == "my"}{tr("suggested_posts_in_group_by_you", $count)}{else}{tr("suggested_posts_in_group", $count)}{/if}

{foreach $posts as $post} {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true} {/foreach} diff --git a/Web/Presenters/templates/Group/View.xml b/Web/Presenters/templates/Group/View.xml index 4a588c135..5d89b1bf9 100644 --- a/Web/Presenters/templates/Group/View.xml +++ b/Web/Presenters/templates/Group/View.xml @@ -92,11 +92,11 @@
{presenter "openvk!Wall->wallEmbedded", -$club->getId()} diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 3f230a288..27284ab94 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -301,7 +301,7 @@ $(document).on("click", "#publish_post", async (e) => { } NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); - document.getElementById("cound").innerHTML = tr("x_suggested_posts_in_group", post.new_count) + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" }), Function.noop]); @@ -342,5 +342,5 @@ $(document).on("click", "#decline_post", async (e) => { NewNotification(tr("suggestion_succefully_declined"), "", null); e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - document.getElementById("cound").innerHTML = tr("x_suggested_posts_in_group", post) + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) }) \ No newline at end of file diff --git a/locales/en.strings b/locales/en.strings index e7f616aca..55290b2a0 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -302,8 +302,19 @@ "group_limited_post" = "Suggestions"; "group_closed_post" = "Closed"; "suggest_new" = "Suggest post"; -"show_suggested_posts" = "$1 suggested posts by you"; -"show_suggested_posts_everyone" = "$1 suggested posts"; + +"suggested_by_you_zero" = "$1 suggested posts by you"; +"suggested_by_you_one" = "One suggested post by you"; +"suggested_by_you_few" = "$1 suggested posts by you"; +"suggested_by_you_many" = "$1 suggested posts by you"; +"suggested_by_you_other" = "$1 suggested posts by you"; + +"suggested_by_everyone_zero" = "$1 suggested posts"; +"suggested_by_everyone_one" = "One suggested post"; +"suggested_by_everyone_few" = "$1 suggested posts"; +"suggested_by_everyone_many" = "$1 suggested posts"; +"suggested_by_everyone_other" = "$1 suggested posts"; + "group_hide_from_global_feed" = "Don't display posts in the global feed"; "suggested_posts_by_you" = "Suggested posts by you"; "suggested_posts_by_everyone" = "Suggested posts"; @@ -316,8 +327,17 @@ "decline_suggested" = "Decline"; "publishing_suggested_post" = "Publishing suggested post"; -"x_suggested_posts_in_group" = "This group has $1 suggested posts"; -"x_suggested_posts_in_group_by_you" = "You suggested $1 posts to this group"; +"suggested_posts_in_group_zero" = "You've looked at all the suggested posts, congratulations!"; +"suggested_posts_in_group_one" = "This group has one suggested post"; +"suggested_posts_in_group_few" = "This group has $1 suggested posts"; +"suggested_posts_in_group_many" = "This group has $1 suggested posts"; +"suggested_posts_in_group_other" = "This group has $1 suggested posts"; + +"suggested_posts_in_group_by_you_zero" = "You haven't suggested any posts to this group"; +"suggested_posts_in_group_by_you_one" = "You suggested one post to this group"; +"suggested_posts_in_group_by_you_few" = "You suggested $1 posts to this group"; +"suggested_posts_in_group_by_you_many" = "You suggested $1 posts to this group"; +"suggested_posts_in_group_by_you_other" = "You suggested $1 posts to this group"; "suggestion_succefully_published" = "Post successfully published"; "suggestion_succefully_declined" = "Post successfully declined"; diff --git a/locales/ru.strings b/locales/ru.strings index 47a769422..ae98c60f4 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -287,8 +287,18 @@ "group_limited_post" = "Предложка"; "group_closed_post" = "Закрытая"; "suggest_new" = "Предложить новость"; -"show_suggested_posts" = "$1 предложенных вами записей"; -"show_suggested_posts_everyone" = "$1 предложенных записей"; +"suggested_by_you_zero" = "$1 предложенных вами записей"; +"suggested_by_you_one" = "Одна предложенная вами запись"; +"suggested_by_you_few" = "$1 предложенные вами записи"; +"suggested_by_you_many" = "$1 предложенных вами записей"; +"suggested_by_you_other" = "$1 предложенных вами записей"; + +"suggested_by_everyone_zero" = "$1 предложенных записей"; +"suggested_by_everyone_one" = "Одна предложенная запись"; +"suggested_by_everyone_few" = "$1 предложенные записи"; +"suggested_by_everyone_many" = "$1 предложенных записей"; +"suggested_by_everyone_other" = "$1 предложенных записей"; + "group_hide_from_global_feed" = "Не отображать публикации в глобальной ленте"; "suggested_posts_by_you" = "Предложенные вами записи"; "suggested_posts_by_everyone" = "Предложенные записи"; @@ -301,8 +311,17 @@ "decline_suggested" = "Отклонить"; "publishing_suggested_post" = "Публикация предложенной записи"; -"x_suggested_posts_in_group" = "В эту группу предложили $1 записей"; -"x_suggested_posts_in_group_by_you" = "Вы предложили в эту группу $1 записей"; +"suggested_posts_in_group_zero" = "Вы посмотрели всю предложку, поздравляю!"; +"suggested_posts_in_group_one" = "В эту группу предложили одну запись"; +"suggested_posts_in_group_few" = "В эту группу предложили $1 записи"; +"suggested_posts_in_group_many" = "В эту группу предложили $1 записей"; +"suggested_posts_in_group_other" = "В эту группу предложили $1 записей"; + +"suggested_posts_in_group_by_you_zero" = "Вы не предлагали в эту группу никаких записей"; +"suggested_posts_in_group_by_you_one" = "Вы предложили в эту группу одну запись"; +"suggested_posts_in_group_by_you_few" = "Вы предложили в эту группу $1 записи"; +"suggested_posts_in_group_by_you_many" = "Вы предложили в эту группу $1 записей"; +"suggested_posts_in_group_by_you_other" = "Вы предложили в эту группу $1 записей"; "suggestion_succefully_published" = "Запись успешно опубликована"; "suggestion_succefully_declined" = "Запись успешно отклонена"; From c7e76ccb1168d5d6743e4b377920045ee52e83bf Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:36:25 +0300 Subject: [PATCH 14/34] newlines --- Web/Presenters/GroupPresenter.php | 2 +- Web/Presenters/templates/components/notifications/6/_14_5_.xml | 2 +- Web/Presenters/templates/components/notifications/7/_18_5_.xml | 2 +- Web/static/css/main.css | 2 +- Web/static/js/al_wall.js | 2 +- install/sqls/00039-suggest-posts.sql | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 2db88baaf..e1ad1ca06 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -473,4 +473,4 @@ function renderSuggestedAll(int $id) $this->template->page = (int) ($this->queryParam("p") ?? 1); $this->template->_template = "Group/Suggested.xml"; } -} \ No newline at end of file +} diff --git a/Web/Presenters/templates/components/notifications/6/_14_5_.xml b/Web/Presenters/templates/components/notifications/6/_14_5_.xml index ab77cb94a..09b03c706 100644 --- a/Web/Presenters/templates/components/notifications/6/_14_5_.xml +++ b/Web/Presenters/templates/components/notifications/6/_14_5_.xml @@ -4,4 +4,4 @@ {_group} {$club->getName()} {_nt_accepted_your_post} -{_nt_post_small}. \ No newline at end of file +{_nt_post_small}. diff --git a/Web/Presenters/templates/components/notifications/7/_18_5_.xml b/Web/Presenters/templates/components/notifications/7/_18_5_.xml index 4c012edd6..4eee6670c 100644 --- a/Web/Presenters/templates/components/notifications/7/_18_5_.xml +++ b/Web/Presenters/templates/components/notifications/7/_18_5_.xml @@ -2,4 +2,4 @@ {_nt_in_club} {$club->getName()} -{_nt_new_suggested_posts} \ No newline at end of file +{_nt_new_suggested_posts} diff --git a/Web/static/css/main.css b/Web/static/css/main.css index 22aa420db..618f9de1c 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2713,4 +2713,4 @@ body.article .floating_sidebar, body.article .page_content { .suggestionControls { text-align: center; -} \ No newline at end of file +} diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 27284ab94..b25337fdc 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -343,4 +343,4 @@ $(document).on("click", "#decline_post", async (e) => { NewNotification(tr("suggestion_succefully_declined"), "", null); e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) -}) \ No newline at end of file +}) diff --git a/install/sqls/00039-suggest-posts.sql b/install/sqls/00039-suggest-posts.sql index 321c2a6a9..2437c5e2a 100644 --- a/install/sqls/00039-suggest-posts.sql +++ b/install/sqls/00039-suggest-posts.sql @@ -1 +1 @@ -ALTER TABLE `posts` ADD `suggested` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `deleted`; \ No newline at end of file +ALTER TABLE `posts` ADD `suggested` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `deleted`; From 9ff4ff4b4b237319c863e419a94f976006a44a81 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 6 Aug 2023 21:06:12 +0300 Subject: [PATCH 15/34] int --- Web/Models/Entities/Postable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Web/Models/Entities/Postable.php b/Web/Models/Entities/Postable.php index b4f8b4c6b..c9f6cc57a 100644 --- a/Web/Models/Entities/Postable.php +++ b/Web/Models/Entities/Postable.php @@ -33,7 +33,7 @@ function getOwner(bool $real = false): RowModel { $oid = (int) $this->getRecord()->owner; if(!$real && $this->isAnonymous()) - $oid = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]; + $oid = (int) OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["account"]; if($oid > 0) return (new Users)->get($oid); From be85edf4c283e4d701c8ea04e58a101e99f9d5ab Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 6 Aug 2023 22:36:09 +0300 Subject: [PATCH 16/34] Update loaders and add avtopodgruzka postov --- Web/Presenters/templates/Group/Suggested.xml | 23 +++++----- Web/static/css/main.css | 5 +++ Web/static/js/al_wall.js | 44 +++++++++++++++++++- locales/en.strings | 2 + locales/ru.strings | 2 + 5 files changed, 65 insertions(+), 11 deletions(-) diff --git a/Web/Presenters/templates/Group/Suggested.xml b/Web/Presenters/templates/Group/Suggested.xml index 93ec70253..b3e4ad208 100644 --- a/Web/Presenters/templates/Group/Suggested.xml +++ b/Web/Presenters/templates/Group/Suggested.xml @@ -12,15 +12,18 @@ {include "../components/error.xml", title => "", description => $type == "my" ? tr("no_suggested_posts_by_you") : tr("no_suggested_posts_by_people")} {else}

{if $type == "my"}{tr("suggested_posts_in_group_by_you", $count)}{else}{tr("suggested_posts_in_group", $count)}{/if}

- {foreach $posts as $post} - {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true} - {/foreach} +
+ {foreach $posts as $post} + {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true} + {/foreach} + + {include "../components/paginator.xml", conf => (object) [ + "page" => $page, + "count" => $count, + "amount" => sizeof($posts), + "perPage" => OPENVK_DEFAULT_PER_PAGE, + "atBottom" => true, + ]} +
{/if} - {include "../components/paginator.xml", conf => (object) [ - "page" => $page, - "count" => $count, - "amount" => sizeof($posts), - "perPage" => OPENVK_DEFAULT_PER_PAGE, - "atBottom" => true, - ]} {/block} diff --git a/Web/static/css/main.css b/Web/static/css/main.css index 618f9de1c..b1fad4f01 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2714,3 +2714,8 @@ body.article .floating_sidebar, body.article .page_content { .suggestionControls { text-align: center; } + +.button.loaded { + background: #595959 url("/assets/packages/static/openvk/img/loading_mini.gif") no-repeat 50% 50%; + padding: 16px 40px 6px 4px; +} diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index b25337fdc..f4f543f8b 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -277,6 +277,9 @@ $(document).on("click", "#publish_post", async (e) => { let post; try { + e.currentTarget.classList.add("loaded") + e.currentTarget.setAttribute("value", "") + e.currentTarget.setAttribute("id", "") post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value) } catch(ex) { switch(ex.code) { @@ -297,12 +300,19 @@ $(document).on("click", "#publish_post", async (e) => { break; } + e.currentTarget.setAttribute("value", tr("publish_suggested")) + e.currentTarget.classList.remove("loaded") + e.currentTarget.setAttribute("id", "publish_post") return 0; } NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + + if(document.querySelectorAll(".post.post-divider").length < 1 && post.new_count > 0) { + loadMoreSuggestedPosts() + } }), Function.noop]); document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') @@ -314,7 +324,9 @@ $(document).on("click", "#decline_post", async (e) => { let post; try { - e.currentTarget.parentNode.parentNode.insertAdjacentHTML("afterbegin", ``) + e.currentTarget.classList.add("loaded") + e.currentTarget.setAttribute("value", "") + e.currentTarget.setAttribute("id", "") post = await API.Wall.declinePost(id) } catch(ex) { switch(ex.code) { @@ -335,6 +347,9 @@ $(document).on("click", "#decline_post", async (e) => { break; } + e.currentTarget.setAttribute("value", tr("decline_suggested")) + e.currentTarget.setAttribute("id", "decline_post") + e.currentTarget.classList.remove("loaded") return 0; } finally { u("#deleteMe").remove() @@ -343,4 +358,31 @@ $(document).on("click", "#decline_post", async (e) => { NewNotification(tr("suggestion_succefully_declined"), "", null); e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) + + if(document.querySelectorAll(".post.post-divider").length < 1 && post > 0) { + loadMoreSuggestedPosts() + } }) + +function loadMoreSuggestedPosts() +{ + let xhr = new XMLHttpRequest + xhr.open("GET", location.href) + + xhr.onloadstart = () => { + document.getElementById("postz").innerHTML = `` + } + + xhr.onload = () => { + let parser = new DOMParser() + let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz") + + document.getElementById("postz").innerHTML = body.innerHTML + } + + xhr.onerror = () => { + document.getElementById("postz").innerHTML = tr("error_loading_suggest") + } + + xhr.send() +} diff --git a/locales/en.strings b/locales/en.strings index 55290b2a0..2d245a98a 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -326,6 +326,8 @@ "publish_suggested" = "Accept"; "decline_suggested" = "Decline"; +"error_loading_suggest" = "Error when loading new posts"; + "publishing_suggested_post" = "Publishing suggested post"; "suggested_posts_in_group_zero" = "You've looked at all the suggested posts, congratulations!"; "suggested_posts_in_group_one" = "This group has one suggested post"; diff --git a/locales/ru.strings b/locales/ru.strings index ae98c60f4..5b033e7c3 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -310,6 +310,8 @@ "publish_suggested" = "Опубликовать запись"; "decline_suggested" = "Отклонить"; +"error_loading_suggest" = "Не удалось подгрузить новые посты"; + "publishing_suggested_post" = "Публикация предложенной записи"; "suggested_posts_in_group_zero" = "Вы посмотрели всю предложку, поздравляю!"; "suggested_posts_in_group_one" = "В эту группу предложили одну запись"; From c4c476ed8b07bd3d0200bc1b21bbf2859cd4562e Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 6 Aug 2023 22:49:28 +0300 Subject: [PATCH 17/34] Update JOERGK.strings --- locales/en.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.strings b/locales/en.strings index 2d245a98a..15681897e 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -343,7 +343,7 @@ "suggestion_succefully_published" = "Post successfully published"; "suggestion_succefully_declined" = "Post successfully declined"; -"suggestion_press_to_go" = "Click to show him"; +"suggestion_press_to_go" = "Click to show it"; "error_declining_invalid_post" = "Error when declining post: post does not exists"; "error_declining_not_suggested_post" = "Error when declining post: post is not suggested"; From 222601383df5b4be287db3e81d08cd5be5f2aa50 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 7 Aug 2023 09:30:57 +0300 Subject: [PATCH 18/34] Blin --- VKAPI/Handlers/Wall.php | 118 +++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 67 deletions(-) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 0f5fa2c3f..a8bf9721d 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -57,8 +57,6 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 case "postponed": $this->fail(66666, "Otlojka is not implemented :)"); break; - # В вкапи, походу, нету метода, который бы публиковал запись из предложки. - # Либо он закрыт для неофициальных клиентов, как gifts.send case "suggests": if($owner_id < 0) { if($wallOnwer->getWallType() != 2) @@ -419,7 +417,7 @@ function getById(string $posts, int $extended = 0, string $fields = "", User $us ]; } - function post(string $owner_id, string $message = "", int $from_group = 0, int $signed = 0, string $attachments = ""): object + function post(string $owner_id, string $message = "", int $from_group = 0, int $signed = 0, string $attachments = "", int $post_id = 0): object { $this->requireUser(); $this->willExecuteWriteAction(); @@ -440,6 +438,45 @@ function post(string $owner_id, string $message = "", int $from_group = 0, int $ if($canPost == false) $this->fail(15, "Access denied"); + if($post_id > 0) { + if($owner_id > 0) { + $this->fail(62, "Suggested posts available only at groups"); + } + + $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); + + if(!$post || $post->isDeleted()) + $this->fail(32, "Invald post"); + + if($post->getSuggestionType() == 0) + $this->fail(20, "Post is not suggested"); + + if($post->getSuggestionType() == 2) + $this->fail(16, "Post is declined"); + + if(!$post->canBePinnedBy($this->getUser())) + $this->fail(51, "Access denied"); + + $author = $post->getOwner(); + $flags = 0; + $flags |= 0b10000000; + + if($signed == 1) + $flags |= 0b01000000; + + $post->setSuggested(0); + $post->setCreated(time()); + $post->setFlags($flags); + + if(!empty($message) && iconv_strlen($message) > 0) + $post->setContent($message); + + $post->save(); + (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + + return (object)["post_id" => $post->getVirtualId()]; + } + $anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"]; if($wallOwner instanceof Club && $from_group == 1 && $signed != 1 && $anon) { $manager = $wallOwner->getManager($this->getUser()); @@ -837,78 +874,25 @@ function deleteComment(int $comment_id) { return 1; } - # !!! Нестандартный метод - function acceptPost(int $club, int $post_id, string $new_message = "", bool $sign = true) + function delete(int $owner_id, int $post_id) { $this->requireUser(); $this->willExecuteWriteAction(); - if($club < 0) { - $this->fail(62, "Club's id is negative"); - } - - $post = (new PostsRepo)->getPostById($club * -1, $post_id, true); + $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); if(!$post || $post->isDeleted()) - $this->fail(32, "Invald post"); - - if($post->getSuggestionType() == 0) - $this->fail(20, "Post is not suggested"); + $this->fail(583, "Invalid post"); - if($post->getSuggestionType() == 2) - $this->fail(16, "Post is declined"); - - if(!$post->canBePinnedBy($this->getUser())) - $this->fail(51, "Access denied"); - - $author = $post->getOwner(); - $flags = 0; - $flags |= 0b10000000; - - if($sign) - $flags |= 0b01000000; - - $post->setSuggested(0); - $post->setCreated(time()); - $post->setFlags($flags); - - if(!empty($new_message) && iconv_strlen($new_message) > 0) - $post->setContent($new_message); - - $post->save(); - (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); - - return 1; - } - - # !!! Нестандартный метод - function declinePost(int $club, int $post_id) - { - $this->requireUser(); - $this->willExecuteWriteAction(); + $wallOwner = $post->getWallOwner(); - if($club < 0) { - $this->fail(62, "Club's id is negative"); - } - - $post = (new PostsRepo)->getPostById($club * -1, $post_id, true); - - if(!$post || $post->isDeleted()) - $this->fail(32, "Invald post"); - - if($post->getSuggestionType() == 0) - $this->fail(20, "Post is not suggested"); - - if($post->getSuggestionType() == 2) - $this->fail(16, "Post is already declined"); + if($post->getOwnerPost() == $this->getUser()->getId() || $post->getTargetWall() == $this->getUser()->getId() || $owner_id < 0 && $wallOwner->canBeModifiedBy($this->getUser())) { + $post->unwire(); + $post->delete(); - if(!$post->canBePinnedBy($this->getUser())) - $this->fail(51, "Access denied"); - - $post->setSuggested(2); - $post->setDeleted(1); - $post->save(); - - return 1; + return 1; + } else { + $this->fail(15, "Access denied"); + } } private function getApiPhoto($attachment) { From ccf618a5ab6d7f5bb5230a89962d76f74b443ab0 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Wed, 9 Aug 2023 12:53:36 +0300 Subject: [PATCH 19/34] Remove repeated code, fix loaded buttons on chr... ...ome and fix getting suggested posts via API.Wall.getPost --- ServiceAPI/Wall.php | 7 ++- Web/Presenters/GroupPresenter.php | 53 ++++--------------- Web/Presenters/templates/@layout.xml | 2 +- Web/Presenters/templates/Group/View.xml | 2 +- .../components/notifications/7/_18_5_.xml | 2 +- Web/routes.yml | 4 +- Web/static/css/main.css | 9 +++- 7 files changed, 28 insertions(+), 51 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 1b9bcabb6..69397e2d7 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -2,7 +2,7 @@ namespace openvk\ServiceAPI; use openvk\Web\Models\Entities\Post; use openvk\Web\Models\Entities\User; -use openvk\Web\Models\Entities\Notifications\{PostAcceptedNotification}; +use openvk\Web\Models\Entities\Notifications\PostAcceptedNotification; use openvk\Web\Models\Repositories\{Posts, Notes}; class Wall implements Handler @@ -22,7 +22,10 @@ function getPost(int $id, callable $resolve, callable $reject): void { $post = $this->posts->get($id); if(!$post || $post->isDeleted()) - $reject("No post with id=$id"); + $reject(53, "No post with id=$id"); + + if($post->getSuggestionType() != 0) + $reject(25, "Can't get suggested post"); $res = (object) []; $res->id = $post->getId(); diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index e1ad1ca06..07c73c183 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -410,7 +410,7 @@ function renderChangeOwner(int $id, int $newOwnerId): void $this->flashFail("succ", tr("information_-1"), tr("group_owner_setted", $newOwner->getCanonicalName(), $club->getName())); } - function renderSuggestedThisUser(int $id) + function renderSuggested(int $id): void { $this->assertUserLoggedIn(); @@ -420,57 +420,26 @@ function renderSuggestedThisUser(int $id) else $this->template->club = $club; - if($club->getWallType() == 1) { - $this->flash("err", tr("error_suggestions"), tr("error_suggestions_closed")); - $this->redirect("/club".$club->getId()); - } - if($club->getWallType() == 0) { - $this->flash("err", tr("error_suggestions"), tr("error_suggestions_open")); - $this->redirect("/club".$club->getId()); - } - - if($club->canBeModifiedBy($this->user->identity)) { - $this->flash("err", tr("error_suggestions"), "No sense"); - $this->redirect("/club".$club->getId()); - } - - $this->template->posts = (new Posts)->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1)); - $this->template->count = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); - $this->template->type = "my"; - $this->template->page = (int) ($this->queryParam("p") ?? 1); - $this->template->_template = "Group/Suggested.xml"; - } - - function renderSuggestedAll(int $id) - { - $this->assertUserLoggedIn(); - - $club = $this->clubs->get($id); - if(!$club) - $this->notFound(); - else - $this->template->club = $club; - - if($club->getWallType() == 1) { $this->flash("err", tr("error_suggestions"), tr("error_suggestions_closed")); $this->redirect("/club".$club->getId()); } - - if($club->getWallType() == 0) { + + if($club->getWallType() == 1) { $this->flash("err", tr("error_suggestions"), tr("error_suggestions_open")); $this->redirect("/club".$club->getId()); } - + if(!$club->canBeModifiedBy($this->user->identity)) { - $this->flash("err", tr("error_suggestions"), tr("error_suggestions_access")); - $this->redirect("/club".$club->getId()); + $this->template->posts = (new Posts)->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1)); + $this->template->count = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); + $this->template->type = "my"; + } else { + $this->template->posts = (new Posts)->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1)); + $this->template->count = (new Posts)->getSuggestedPostsCount($club->getId()); + $this->template->type = "everyone"; } - $this->template->posts = (new Posts)->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1)); - $this->template->count = (new Posts)->getSuggestedPostsCount($club->getId()); - $this->template->type = "everyone"; $this->template->page = (int) ($this->queryParam("p") ?? 1); - $this->template->_template = "Group/Suggested.xml"; } } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 5c006ea5a..e9aecafbc 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -219,7 +219,7 @@ {$club->getName()} - + ({$club->getSuggestedPostsCount()}) diff --git a/Web/Presenters/templates/Group/View.xml b/Web/Presenters/templates/Group/View.xml index 5d89b1bf9..8abfc5ef8 100644 --- a/Web/Presenters/templates/Group/View.xml +++ b/Web/Presenters/templates/Group/View.xml @@ -96,7 +96,7 @@
{presenter "openvk!Wall->wallEmbedded", -$club->getId()} diff --git a/Web/Presenters/templates/components/notifications/7/_18_5_.xml b/Web/Presenters/templates/components/notifications/7/_18_5_.xml index 4eee6670c..6f1591f0e 100644 --- a/Web/Presenters/templates/components/notifications/7/_18_5_.xml +++ b/Web/Presenters/templates/components/notifications/7/_18_5_.xml @@ -1,5 +1,5 @@ {var $club = $notification->getModel(1)} {_nt_in_club} -{$club->getName()} +{$club->getName()} {_nt_new_suggested_posts} diff --git a/Web/routes.yml b/Web/routes.yml index 2dbc8a2b5..6b1c1be47 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -202,9 +202,7 @@ routes: - url: "/club{num}/setAdmin" handler: "Group->modifyAdmin" - url: "/club{num}/suggested" - handler: "Group->suggestedThisUser" - - url: "/club{num}/suggested/all" - handler: "Group->suggestedAll" + handler: "Group->suggested" - url: "/groups{num}" handler: "User->groups" - url: "/groups_pin" diff --git a/Web/static/css/main.css b/Web/static/css/main.css index b1fad4f01..66fb432a8 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2717,5 +2717,12 @@ body.article .floating_sidebar, body.article .page_content { .button.loaded { background: #595959 url("/assets/packages/static/openvk/img/loading_mini.gif") no-repeat 50% 50%; - padding: 16px 40px 6px 4px; + padding: 2px 9px 7px 39px; + margin-bottom: -6px; +} + +@-moz-document url-prefix() { + .button.loaded { + padding: 16px 40px 6px 4px !important; + } } From 499bec2a505083f30c9a3a1a460bc91405dfcdee Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Wed, 9 Aug 2023 16:38:05 +0300 Subject: [PATCH 20/34] Fix polls --- Web/Models/Entities/Poll.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Web/Models/Entities/Poll.php b/Web/Models/Entities/Poll.php index 6f2885b1f..b88ce1a8e 100644 --- a/Web/Models/Entities/Poll.php +++ b/Web/Models/Entities/Poll.php @@ -4,7 +4,7 @@ use openvk\Web\Util\DateTime; use \UnexpectedValueException; use Nette\InvalidStateException; -use openvk\Web\Models\Repositories\Users; +use openvk\Web\Models\Repositories\{Users, Posts}; use Chandler\Database\DatabaseConnection; use openvk\Web\Models\Exceptions\PollLockedException; use openvk\Web\Models\Exceptions\AlreadyVotedException; @@ -165,7 +165,7 @@ function hasVoted(User $user): bool function canVote(User $user): bool { - return !$this->hasEnded() && !$this->hasVoted($user); + return !$this->hasEnded() && !$this->hasVoted($user) && !is_null($this->getAttachedPost()) && $this->getAttachedPost()->getSuggestionType() == 0; } function vote(User $user, array $optionIds): void @@ -292,4 +292,18 @@ function save(): void ]); } } + + function getAttachedPost() + { + $post = DatabaseConnection::i()->getContext()->table("attachments") + ->where( + ["attachable_type" => static::class, + "attachable_id" => $this->getId()])->fetch(); + + if(!is_null($post->target_id)) { + return (new Posts)->get($post->target_id); + } else { + return NULL; + } + } } From f1fdb15bb9f3647490869ce6616d8f0413f285c2 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:28:48 +0300 Subject: [PATCH 21/34] Fihes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Теперь уведомление о принятии поста не приходит, если вы приняли свой же пост Пофикшен баг перехода в предложку Добавлен старый вид постов в предложке Теперь счётчик постов в предложке у прикреплённой группы обновляется при принятии или отклонении поста Убрано всплывающее уведомление об отклонении поста (оно раздражает) Теперь если вы посмотрели все посты на одной странице (не на первой) и на ней не осталось постов, вас телепортирует на предыдущую страницу --- ServiceAPI/Wall.php | 3 +- VKAPI/Handlers/Wall.php | 4 +- Web/Presenters/templates/@layout.xml | 2 +- Web/Presenters/templates/Group/Suggested.xml | 7 ++- .../components/notifications/7/_18_5_.xml | 2 +- .../templates/components/post/oldpost.xml | 8 ++- Web/static/js/al_wall.js | 53 ++++++++++++++++--- 7 files changed, 65 insertions(+), 14 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 69397e2d7..9c4b5e0e0 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -155,7 +155,8 @@ function acceptPost(int $id, bool $sign, string $content, callable $resolve, cal $post->save(); - (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + if($author->getId() != $this->user->getId()) + (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); $resolve(["id" => $post->getPrettyId(), "new_count" => $this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())]); } diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index a8bf9721d..058b40e60 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -472,7 +472,9 @@ function post(string $owner_id, string $message = "", int $from_group = 0, int $ $post->setContent($message); $post->save(); - (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + + if($author->getId() != $this->getUser()->getId()) + (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); return (object)["post_id" => $post->getVirtualId()]; } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index e9aecafbc..8955daf00 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -219,7 +219,7 @@ {$club->getName()} - + ({$club->getSuggestedPostsCount()}) diff --git a/Web/Presenters/templates/Group/Suggested.xml b/Web/Presenters/templates/Group/Suggested.xml index b3e4ad208..56e836eff 100644 --- a/Web/Presenters/templates/Group/Suggested.xml +++ b/Web/Presenters/templates/Group/Suggested.xml @@ -13,8 +13,13 @@ {else}

{if $type == "my"}{tr("suggested_posts_in_group_by_you", $count)}{else}{tr("suggested_posts_in_group", $count)}{/if}

+ {var $microblog = $thisUser->hasMicroblogEnabled()} {foreach $posts as $post} - {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true} + {if $microblog} + {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} + {else} + {include "../components/post/oldpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} + {/if} {/foreach} {include "../components/paginator.xml", conf => (object) [ diff --git a/Web/Presenters/templates/components/notifications/7/_18_5_.xml b/Web/Presenters/templates/components/notifications/7/_18_5_.xml index 6f1591f0e..b9cda4750 100644 --- a/Web/Presenters/templates/components/notifications/7/_18_5_.xml +++ b/Web/Presenters/templates/components/notifications/7/_18_5_.xml @@ -1,5 +1,5 @@ {var $club = $notification->getModel(1)} {_nt_in_club} -{$club->getName()} +{$club->getName()} {_nt_new_suggested_posts} diff --git a/Web/Presenters/templates/components/post/oldpost.xml b/Web/Presenters/templates/components/post/oldpost.xml index c893e2894..ee99519b8 100644 --- a/Web/Presenters/templates/components/post/oldpost.xml +++ b/Web/Presenters/templates/components/post/oldpost.xml @@ -50,7 +50,7 @@ {/if}
- + {$post->getPublicationTime()}{if $post->isPinned()}, {_pinned}{/if} @@ -59,7 +59,7 @@
- {$post->getText()|noescape} + {$post->getText()|noescape}
@@ -67,6 +67,10 @@
+
+ + +

 ! Этот пост был размещён за взятку. diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index f4f543f8b..1812ac415 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -308,9 +308,22 @@ $(document).on("click", "#publish_post", async (e) => { NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + + if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { + document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count + + if(post.new_count < 1) { + u("object a[href='"+location.pathname+"']").remove() + } + } + + if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } else { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } - if(document.querySelectorAll(".post.post-divider").length < 1 && post.new_count > 0) { + if(document.querySelectorAll(".post").length < 1 && post.new_count > 0) { loadMoreSuggestedPosts() } }), Function.noop]); @@ -351,15 +364,27 @@ $(document).on("click", "#decline_post", async (e) => { e.currentTarget.setAttribute("id", "decline_post") e.currentTarget.classList.remove("loaded") return 0; - } finally { - u("#deleteMe").remove() } - NewNotification(tr("suggestion_succefully_declined"), "", null); - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + //NewNotification(tr("suggestion_succefully_declined"), "", null); + + if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } else { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) - if(document.querySelectorAll(".post.post-divider").length < 1 && post > 0) { + if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { + document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post + + if(post < 1) { + u("object a[href='"+location.pathname+"']").remove() + } + } + + if(document.querySelectorAll(".post").length < 1 && post > 0) { loadMoreSuggestedPosts() } }) @@ -377,6 +402,20 @@ function loadMoreSuggestedPosts() let parser = new DOMParser() let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz") + if(body.querySelectorAll(".post").length < 1) { + let url = new URL(location.href) + url.searchParams.set("p", url.searchParams.get("p") - 1) + + if(url.searchParams.get("p") < 1) { + return 0; + } + + // OVK AJAX ROUTING ?????????? + history.pushState({}, "", url) + + loadMoreSuggestedPosts() + } + document.getElementById("postz").innerHTML = body.innerHTML } From adef21d3a93e19413bf1ae8703248523512ad7c3 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sat, 12 Aug 2023 12:26:39 +0300 Subject: [PATCH 22/34] Remove ability to delete your accepted psto --- VKAPI/Handlers/Wall.php | 3 +++ Web/Models/Entities/Post.php | 3 +++ Web/Presenters/WallPresenter.php | 3 +++ Web/static/js/al_wall.js | 4 ++-- locales/en.strings | 1 + locales/ru.strings | 1 + 6 files changed, 13 insertions(+), 2 deletions(-) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 058b40e60..9d1f0ad5f 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -887,6 +887,9 @@ function delete(int $owner_id, int $post_id) $wallOwner = $post->getWallOwner(); + if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->getUser()) && $post->getWallOwner()->getWallType() != 1) + $this->fail(12, "Access denied: you can't delete your accepted post."); + if($post->getOwnerPost() == $this->getUser()->getId() || $post->getTargetWall() == $this->getUser()->getId() || $owner_id < 0 && $wallOwner->canBeModifiedBy($this->getUser())) { $post->unwire(); $post->delete(); diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 5f2d3d4d2..3374301b1 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -207,6 +207,9 @@ function canBePinnedBy(User $user): bool function canBeDeletedBy(User $user): bool { + if($this->getTargetWall() < 0 && !$this->getWallOwner()->canBeModifiedBy($user) && $this->getWallOwner()->getWallType() != 1) + return false; + return $this->getOwnerPost() === $user->getId() || $this->canBePinnedBy($user); } diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 39b7e32bc..1dd19349c 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -492,6 +492,9 @@ function renderDelete(int $wall, int $post_id): void else $canBeDeletedByOtherUser = false; if(!is_null($user)) { + if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->user->identity) && $post->getWallOwner()->getWallType() != 1) + $this->flashFail("err", tr("failed_to_delete_post"), tr("error_deleting_suggested")); + if($post->getOwnerPost() == $user || $post->getTargetWall() == $user || $canBeDeletedByOtherUser) { $post->unwire(); $post->delete(); diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 1812ac415..b1ca61171 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -323,7 +323,7 @@ $(document).on("click", "#publish_post", async (e) => { e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" } - if(document.querySelectorAll(".post").length < 1 && post.new_count > 0) { + if(document.querySelectorAll(".post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) { loadMoreSuggestedPosts() } }), Function.noop]); @@ -384,7 +384,7 @@ $(document).on("click", "#decline_post", async (e) => { } } - if(document.querySelectorAll(".post").length < 1 && post > 0) { + if(document.querySelectorAll(".post").length < 1 && post > 0 && document.querySelector(".paginator") != null) { loadMoreSuggestedPosts() } }) diff --git a/locales/en.strings b/locales/en.strings index ff1460161..f4a2fb56e 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -1180,6 +1180,7 @@ "media_file_corrupted_or_too_large" = "The media content file is corrupted or too large."; "post_is_empty_or_too_big" = "The post is empty or too big."; "post_is_too_big" = "The post is too big."; +"error_deleting_suggested" = "You can't delete your accepted post"; /* Admin actions */ diff --git a/locales/ru.strings b/locales/ru.strings index 0f37bfe8b..87c966e4a 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -1080,6 +1080,7 @@ "media_file_corrupted_or_too_large" = "Файл медиаконтента повреждён или слишком велик."; "post_is_empty_or_too_big" = "Пост пустой или слишком большой."; "post_is_too_big" = "Пост слишком большой."; +"error_deleting_suggested" = "Вы не можете удалить ваш принятый пост"; /* Admin actions */ From f58518300cd1b323b5de99200e58bb8059e49b8c Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 13 Aug 2023 19:17:34 +0300 Subject: [PATCH 23/34] oi blin --- VKAPI/Handlers/Wall.php | 2 +- Web/Models/Entities/Post.php | 2 +- Web/Presenters/WallPresenter.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 9d1f0ad5f..3b8a9d3d4 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -887,7 +887,7 @@ function delete(int $owner_id, int $post_id) $wallOwner = $post->getWallOwner(); - if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->getUser()) && $post->getWallOwner()->getWallType() != 1) + if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->getUser()) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) $this->fail(12, "Access denied: you can't delete your accepted post."); if($post->getOwnerPost() == $this->getUser()->getId() || $post->getTargetWall() == $this->getUser()->getId() || $owner_id < 0 && $wallOwner->canBeModifiedBy($this->getUser())) { diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index 3374301b1..cfb86003f 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -207,7 +207,7 @@ function canBePinnedBy(User $user): bool function canBeDeletedBy(User $user): bool { - if($this->getTargetWall() < 0 && !$this->getWallOwner()->canBeModifiedBy($user) && $this->getWallOwner()->getWallType() != 1) + if($this->getTargetWall() < 0 && !$this->getWallOwner()->canBeModifiedBy($user) && $this->getWallOwner()->getWallType() != 1 && $this->getSuggestionType() == 0) return false; return $this->getOwnerPost() === $user->getId() || $this->canBePinnedBy($user); diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 1dd19349c..384086548 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -492,7 +492,7 @@ function renderDelete(int $wall, int $post_id): void else $canBeDeletedByOtherUser = false; if(!is_null($user)) { - if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->user->identity) && $post->getWallOwner()->getWallType() != 1) + if($post->getTargetWall() < 0 && !$post->getWallOwner()->canBeModifiedBy($this->user->identity) && $post->getWallOwner()->getWallType() != 1 && $post->getSuggestionType() == 0) $this->flashFail("err", tr("failed_to_delete_post"), tr("error_deleting_suggested")); if($post->getOwnerPost() == $user || $post->getTargetWall() == $user || $canBeDeletedByOtherUser) { From c8ef5ccd6417b28f5dddc8762aa8e70c0593d108 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Tue, 15 Aug 2023 10:21:06 +0300 Subject: [PATCH 24/34] Improvements 2 api --- VKAPI/Handlers/Groups.php | 35 ++++++++++++++++- VKAPI/Handlers/Newsfeed.php | 2 +- VKAPI/Handlers/Wall.php | 41 +++++++++++++++++--- Web/Presenters/templates/@layout.xml | 2 +- Web/Presenters/templates/Group/Suggested.xml | 14 ++++--- 5 files changed, 80 insertions(+), 14 deletions(-) diff --git a/VKAPI/Handlers/Groups.php b/VKAPI/Handlers/Groups.php index 2937795a9..5a5487da3 100644 --- a/VKAPI/Handlers/Groups.php +++ b/VKAPI/Handlers/Groups.php @@ -2,6 +2,7 @@ namespace openvk\VKAPI\Handlers; use openvk\Web\Models\Repositories\Clubs as ClubsRepo; use openvk\Web\Models\Repositories\Users as UsersRepo; +use openvk\Web\Models\Repositories\Posts as PostsRepo; use openvk\Web\Models\Entities\Club; final class Groups extends VKAPIRequestHandler @@ -81,6 +82,22 @@ function get(int $user_id = 0, string $fields = "", int $offset = 0, int $count case "members_count": $rClubs[$i]->members_count = $usr->getFollowersCount(); break; + case "can_suggest": + $rClubs[$i]->can_suggest = !$usr->canBeModifiedBy($this->getUser()) && $usr->getWallType() == 2; + break; + # unstandard feild + case "suggested_count": + if($usr->getWallType() != 2) { + $rClubs[$i]->suggested_count = NULL; + break; + } + + if($usr->canBeModifiedBy($this->getUser())) + $rClubs[$i]->suggested_count = $usr->getSuggestedPostsCount(); + else + $rClubs[$i]->suggested_count = (new PostsRepo)->getSuggestedPostsCountByUser($usr->getId(), $this->getUser()->getId()); + + break; } } } @@ -188,7 +205,23 @@ function getById(string $group_ids = "", string $group_id = "", string $fields = case "description": $response[$i]->description = $clb->getDescription(); break; - case "contacts": + case "can_suggest": + $response[$i]->can_suggest = !$clb->canBeModifiedBy($this->getUser()) && $clb->getWallType() == 2; + break; + # unstandard feild + case "suggested_count": + if($clb->getWallType() != 2) { + $response[$i]->suggested_count = NULL; + break; + } + + if($clb->canBeModifiedBy($this->getUser())) + $response[$i]->suggested_count = $clb->getSuggestedPostsCount(); + else + $response[$i]->suggested_count = (new PostsRepo)->getSuggestedPostsCountByUser($clb->getId(), $this->getUser()->getId()); + + break; + case "contacts": $contacts; $contactTmp = $clb->getManagers(1, true); diff --git a/VKAPI/Handlers/Newsfeed.php b/VKAPI/Handlers/Newsfeed.php index d99924304..4833e7beb 100644 --- a/VKAPI/Handlers/Newsfeed.php +++ b/VKAPI/Handlers/Newsfeed.php @@ -51,7 +51,7 @@ function getGlobal(string $fields = "", int $start_from = 0, int $start_time = 0 { $this->requireUser(); - $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND `posts`.`deleted` = 0"; + $queryBase = "FROM `posts` LEFT JOIN `groups` ON GREATEST(`posts`.`wall`, 0) = 0 AND `groups`.`id` = ABS(`posts`.`wall`) WHERE (`groups`.`hide_from_global_feed` = 0 OR `groups`.`name` IS NULL) AND `posts`.`deleted` = 0 AND `posts`.`suggested` = 0"; if($this->getUser()->getNsfwTolerance() === User::NSFW_INTOLERANT) $queryBase .= " AND `nsfw` = 0"; diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 3b8a9d3d4..4242d46e7 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -49,13 +49,13 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 $cnt = $posts->getPostCountOnUserWall($owner_id); break; case "owner": - $this->fail(66666, "Not implemented :("); + $this->fail(66666, "Not implemented"); break; case "others": - $this->fail(66666, "Not implemented :("); + $this->fail(66666, "Not implemented"); break; case "postponed": - $this->fail(66666, "Otlojka is not implemented :)"); + $this->fail(66666, "Postponed posts are not implemented."); break; case "suggests": if($owner_id < 0) { @@ -149,12 +149,23 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 ]; } + $postType = "post"; + $signerId = NULL; + if($post->getSuggestionType() != 0) { + $postType = "suggest"; + } + + if($post->isSigned()) { + $actualAuthor = $post->getOwner(false); + $signerId = $actualAuthor->getId(); + } + $items[] = (object)[ "id" => $post->getVirtualId(), "from_id" => $from_id, "owner_id" => $post->getTargetWall(), "date" => $post->getPublicationTime()->timestamp(), - "post_type" => "post", + "post_type" => $postType, "text" => $post->getText(false), "copy_history" => $repost, "can_edit" => 0, # TODO @@ -166,6 +177,7 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 "is_explicit" => $post->isExplicit(), "attachments" => $attachments, "post_source" => $post_source, + "signer_id" => $signerId, "comments" => (object)[ "count" => $post->getCommentsCount(), "can_post" => 1 @@ -187,6 +199,9 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 else $groups[] = $from_id * -1; + /*if($post->isSigned()) + $profiles[] = $post->getOwner(false)->getId();*/ + $attachments = NULL; # free attachments so it will not clone everythingg } @@ -324,12 +339,24 @@ function getById(string $posts, int $extended = 0, string $fields = "", User $us ]; } + # TODO: $post->getVkApiType() + $postType = "post"; + $signerId = NULL; + if($post->getSuggestionType() != 0) { + $postType = "suggest"; + } + + if($post->isSigned()) { + $actualAuthor = $post->getOwner(false); + $signerId = $actualAuthor->getId(); + } + $items[] = (object)[ "id" => $post->getVirtualId(), "from_id" => $from_id, "owner_id" => $post->getTargetWall(), "date" => $post->getPublicationTime()->timestamp(), - "post_type" => "post", + "post_type" => $postType, "text" => $post->getText(false), "copy_history" => $repost, "can_edit" => 0, # TODO @@ -340,6 +367,7 @@ function getById(string $posts, int $extended = 0, string $fields = "", User $us "is_pinned" => $post->isPinned(), "is_explicit" => $post->isExplicit(), "post_source" => $post_source, + "signer_id" => $signerId, "attachments" => $attachments, "comments" => (object)[ "count" => $post->getCommentsCount(), @@ -362,6 +390,9 @@ function getById(string $posts, int $extended = 0, string $fields = "", User $us else $groups[] = $from_id * -1; + /*if($post->isSigned()) + $profiles[] = $post->getOwner(false)->getId();*/ + $attachments = NULL; # free attachments so it will not clone everything $repost = NULL; # same } diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index ccb6994ae..389415bbc 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -234,7 +234,7 @@ {$club->getName()} - + ({$club->getSuggestedPostsCount()}) diff --git a/Web/Presenters/templates/Group/Suggested.xml b/Web/Presenters/templates/Group/Suggested.xml index 56e836eff..a7c824f68 100644 --- a/Web/Presenters/templates/Group/Suggested.xml +++ b/Web/Presenters/templates/Group/Suggested.xml @@ -12,14 +12,16 @@ {include "../components/error.xml", title => "", description => $type == "my" ? tr("no_suggested_posts_by_you") : tr("no_suggested_posts_by_people")} {else}

{if $type == "my"}{tr("suggested_posts_in_group_by_you", $count)}{else}{tr("suggested_posts_in_group", $count)}{/if}

-
+
{var $microblog = $thisUser->hasMicroblogEnabled()} {foreach $posts as $post} - {if $microblog} - {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} - {else} - {include "../components/post/oldpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} - {/if} +
+ {if $microblog} + {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} + {else} + {include "../components/post/oldpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} + {/if} +
{/foreach} {include "../components/paginator.xml", conf => (object) [ From 5f51881a5d02f2f07c72d6c00e8da5bbd75f9338 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Thu, 17 Aug 2023 21:19:35 +0300 Subject: [PATCH 25/34] g --- VKAPI/Handlers/Groups.php | 13 +++---------- VKAPI/Handlers/Wall.php | 6 +++--- Web/Models/Entities/Club.php | 16 +++++++++++++--- Web/Presenters/GroupPresenter.php | 2 +- Web/Presenters/templates/@layout.xml | 4 ++-- locales/en.strings | 1 + locales/ru.strings | 1 + themepacks/midnight/stylesheet.css | 15 ++++++++++++++- themepacks/openvk_modern/stylesheet.css | 9 +++++++-- 9 files changed, 45 insertions(+), 22 deletions(-) diff --git a/VKAPI/Handlers/Groups.php b/VKAPI/Handlers/Groups.php index 5a5487da3..ce2432210 100644 --- a/VKAPI/Handlers/Groups.php +++ b/VKAPI/Handlers/Groups.php @@ -91,11 +91,8 @@ function get(int $user_id = 0, string $fields = "", int $offset = 0, int $count $rClubs[$i]->suggested_count = NULL; break; } - - if($usr->canBeModifiedBy($this->getUser())) - $rClubs[$i]->suggested_count = $usr->getSuggestedPostsCount(); - else - $rClubs[$i]->suggested_count = (new PostsRepo)->getSuggestedPostsCountByUser($usr->getId(), $this->getUser()->getId()); + + $rClubs[$i]->suggested_count = $usr->getSuggestedPostsCount($this->getUser()); break; } @@ -215,11 +212,7 @@ function getById(string $group_ids = "", string $group_id = "", string $fields = break; } - if($clb->canBeModifiedBy($this->getUser())) - $response[$i]->suggested_count = $clb->getSuggestedPostsCount(); - else - $response[$i]->suggested_count = (new PostsRepo)->getSuggestedPostsCountByUser($clb->getId(), $this->getUser()->getId()); - + $response[$i]->suggested_count = $clb->getSuggestedPostsCount($this->getUser()); break; case "contacts": $contacts; diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 4242d46e7..0762f730a 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -49,13 +49,13 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 $cnt = $posts->getPostCountOnUserWall($owner_id); break; case "owner": - $this->fail(66666, "Not implemented"); + $this->fail(42, "Not implemented"); break; case "others": - $this->fail(66666, "Not implemented"); + $this->fail(42, "Not implemented"); break; case "postponed": - $this->fail(66666, "Postponed posts are not implemented."); + $this->fail(42, "Postponed posts are not implemented."); break; case "suggests": if($owner_id < 0) { diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 751ccb441..88e8e9761 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -194,7 +194,7 @@ function setShortCode(?string $code = NULL): ?bool function setWall(int $type) { - if($type > 3 || $type < 0) + if($type > 2 || $type < 0) throw new \LogicException("Invalid wall"); $this->stateChanges("wall", $type); @@ -309,9 +309,19 @@ function getFollowers(int $page = 1, int $perPage = 6, string $sort = "follower } } - function getSuggestedPostsCount() + function getSuggestedPostsCount(User $user = NULL) { - $count = (new Posts)->getSuggestedPostsCount($this->getId()); + $count = 0; + + if(is_null($user)) { + return NULL; + } + + if($this->canBeModifiedBy($user)) { + $count = (new Posts)->getSuggestedPostsCount($this->getId()); + } else { + $count = (new Posts)->getSuggestedPostsCountByUser($this->getId(), $user->getId()); + } return $count; } diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 4dd79c119..12f6ce808 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -225,7 +225,7 @@ function renderEdit(int $id): void try { $club->setWall(empty($this->postParam("wall")) ? 0 : (int)$this->postParam("wall")); } catch(\Exception $e) { - $this->flashFail("err", "Fuck you", ""); + $this->flashFail("err", tr("error"), tr("error_invalid_wall_value")); } $club->setAdministrators_List_Display(empty($this->postParam("administrators_list_display")) ? 0 : $this->postParam("administrators_list_display")); diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index 389415bbc..d962253d3 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -233,9 +233,9 @@
{$club->getName()} - + - ({$club->getSuggestedPostsCount()}) + ({$club->getSuggestedPostsCount($thisUser)}) diff --git a/locales/en.strings b/locales/en.strings index f4a2fb56e..9d6cfd51b 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -1181,6 +1181,7 @@ "post_is_empty_or_too_big" = "The post is empty or too big."; "post_is_too_big" = "The post is too big."; "error_deleting_suggested" = "You can't delete your accepted post"; +"error_invalid_wall_value" = "Invalid wall value"; /* Admin actions */ diff --git a/locales/ru.strings b/locales/ru.strings index 87c966e4a..fd464deb1 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -1081,6 +1081,7 @@ "post_is_empty_or_too_big" = "Пост пустой или слишком большой."; "post_is_too_big" = "Пост слишком большой."; "error_deleting_suggested" = "Вы не можете удалить ваш принятый пост"; +"error_invalid_wall_value" = "Некорректное значение стены"; /* Admin actions */ diff --git a/themepacks/midnight/stylesheet.css b/themepacks/midnight/stylesheet.css index 634917c65..dde8442c7 100644 --- a/themepacks/midnight/stylesheet.css +++ b/themepacks/midnight/stylesheet.css @@ -241,4 +241,17 @@ input[type="radio"] { #backdropEditor { background-image: url("/themepack/midnight/0.0.2.8/resource/backdrop-editor.gif") !important; border-color: #473e66 !important; -} \ No newline at end of file +} + +.sugglist { + background-color: #231e33; + border-color: #2c2640 !important; +} + +.sugglist a { + color: #7c94c5; +} + +.button.loaded { + background: #383052 url("/assets/packages/static/openvk/img/loading_mini.gif") no-repeat 50% 50% !important; +} diff --git a/themepacks/openvk_modern/stylesheet.css b/themepacks/openvk_modern/stylesheet.css index 178e8094c..9a280ceca 100644 --- a/themepacks/openvk_modern/stylesheet.css +++ b/themepacks/openvk_modern/stylesheet.css @@ -47,13 +47,13 @@ body { .content_title_expanded { cursor: pointer; - background-image: unset; + background-image: unset !important; padding: 3px 10px; border-top: #e6e6e6 solid 1px; } .content_title_unexpanded { - background-image: unset; + background-image: unset !important; padding: 3px 10px; border-top: #eee solid 1px; } @@ -337,3 +337,8 @@ input[type=checkbox] { { border-top: 1px solid #2f2f2f; } + +.sugglist { + border-top: unset; + border-bottom: 1px solid gray; +} From 6bd475a6ac1ba750983fdf7d7d81bd0171262817 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sat, 19 Aug 2023 22:29:47 +0300 Subject: [PATCH 26/34] openvk.uk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Возможно, приведение кода к кодстайлу (удаление скобочек то есть) --- ServiceAPI/Wall.php | 10 ++++------ VKAPI/Handlers/Wall.php | 14 ++++++-------- Web/Models/Entities/Club.php | 8 +++----- Web/Models/Entities/Poll.php | 5 ++--- Web/Presenters/GroupPresenter.php | 11 +++++------ Web/Presenters/WallPresenter.php | 8 ++------ Web/Presenters/templates/Group/Suggested.xml | 16 +++++++--------- 7 files changed, 29 insertions(+), 43 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 9c4b5e0e0..e6133497a 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -141,18 +141,16 @@ function acceptPost(int $id, bool $sign, string $content, callable $resolve, cal $flags = 0; $flags |= 0b10000000; - if($sign) { + if($sign) $flags |= 0b01000000; - } - + $post->setSuggested(0); $post->setCreated(time()); $post->setFlags($flags); - if(mb_strlen($content) > 0) { + if(mb_strlen($content) > 0) $post->setContent($content); - } - + $post->save(); if($author->getId() != $this->user->getId()) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 0762f730a..b90ebeac2 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -151,9 +151,9 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 $postType = "post"; $signerId = NULL; - if($post->getSuggestionType() != 0) { + if($post->getSuggestionType() != 0) $postType = "suggest"; - } + if($post->isSigned()) { $actualAuthor = $post->getOwner(false); @@ -342,9 +342,9 @@ function getById(string $posts, int $extended = 0, string $fields = "", User $us # TODO: $post->getVkApiType() $postType = "post"; $signerId = NULL; - if($post->getSuggestionType() != 0) { + if($post->getSuggestionType() != 0) $postType = "suggest"; - } + if($post->isSigned()) { $actualAuthor = $post->getOwner(false); @@ -470,9 +470,8 @@ function post(string $owner_id, string $message = "", int $from_group = 0, int $ if($canPost == false) $this->fail(15, "Access denied"); if($post_id > 0) { - if($owner_id > 0) { + if($owner_id > 0) $this->fail(62, "Suggested posts available only at groups"); - } $post = (new PostsRepo)->getPostById($owner_id, $post_id, true); @@ -539,9 +538,8 @@ function post(string $owner_id, string $message = "", int $from_group = 0, int $ $post->setFlags($flags); $post->setApi_Source_Name($this->getPlatform()); - if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2) { + if($owner_id < 0 && !$wallOwner->canBeModifiedBy($this->getUser()) && $wallOwner->getWallType() == 2) $post->setSuggested(1); - } $post->save(); } catch(\LogicException $ex) { diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php index 88e8e9761..9feb29b96 100644 --- a/Web/Models/Entities/Club.php +++ b/Web/Models/Entities/Club.php @@ -313,15 +313,13 @@ function getSuggestedPostsCount(User $user = NULL) { $count = 0; - if(is_null($user)) { + if(is_null($user)) return NULL; - } - if($this->canBeModifiedBy($user)) { + if($this->canBeModifiedBy($user)) $count = (new Posts)->getSuggestedPostsCount($this->getId()); - } else { + else $count = (new Posts)->getSuggestedPostsCountByUser($this->getId(), $user->getId()); - } return $count; } diff --git a/Web/Models/Entities/Poll.php b/Web/Models/Entities/Poll.php index b88ce1a8e..3fea3f9d2 100644 --- a/Web/Models/Entities/Poll.php +++ b/Web/Models/Entities/Poll.php @@ -300,10 +300,9 @@ function getAttachedPost() ["attachable_type" => static::class, "attachable_id" => $this->getId()])->fetch(); - if(!is_null($post->target_id)) { + if(!is_null($post->target_id)) return (new Posts)->get($post->target_id); - } else { + else return NULL; - } } } diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 12f6ce808..7a196439d 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -33,12 +33,11 @@ function renderView(int $id): void $this->template->topicsCount = (new Topics)->getClubTopicsCount($club); } - if(!is_null($this->user->identity) && !$club->canBeModifiedBy($this->user->identity) && $club->getWallType() == 2) { - $this->template->suggestedPostsCountByUser = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); - } - - if(!is_null($this->user->identity) && $club->canBeModifiedBy($this->user->identity) && $club->getWallType() == 2) { - $this->template->suggestedPostsCountByEveryone = (new Posts)->getSuggestedPostsCount($club->getId()); + if(!is_null($this->user->identity) && $club->getWallType() == 2) { + if(!$club->canBeModifiedBy($this->user->identity)) + $this->template->suggestedPostsCountByUser = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); + else + $this->template->suggestedPostsCountByEveryone = (new Posts)->getSuggestedPostsCount($club->getId()); } $this->template->club = $club; diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 384086548..b8e94298a 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -310,9 +310,8 @@ function renderMakePost(int $wall): void $post->setFlags($flags); $post->setNsfw($this->postParam("nsfw") === "on"); - if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { + if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) $post->setSuggested(1); - } $post->save(); } catch (\LengthException $ex) { @@ -351,16 +350,13 @@ function renderMakePost(int $wall): void if($wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2) { $suggsCount = $this->posts->getSuggestedPostsCount($wallOwner->getId()); - # Возможно, это заебёт админов групп, но так они хотя бы про паблик вспомнят - # Мб рандома добавить? if($suggsCount % 10 == 0) { $managers = $wallOwner->getManagers(); $owner = $wallOwner->getOwner(); (new NewSuggestedPostsNotification($owner, $wallOwner))->emit(); - foreach($managers as $manager) { + foreach($managers as $manager) (new NewSuggestedPostsNotification($manager->getUser(), $wallOwner))->emit(); - } } $this->redirect("/club".$wallOwner->getId()."/suggested"); diff --git a/Web/Presenters/templates/Group/Suggested.xml b/Web/Presenters/templates/Group/Suggested.xml index a7c824f68..1c8826751 100644 --- a/Web/Presenters/templates/Group/Suggested.xml +++ b/Web/Presenters/templates/Group/Suggested.xml @@ -14,15 +14,13 @@

{if $type == "my"}{tr("suggested_posts_in_group_by_you", $count)}{else}{tr("suggested_posts_in_group", $count)}{/if}

{var $microblog = $thisUser->hasMicroblogEnabled()} - {foreach $posts as $post} -
- {if $microblog} - {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} - {else} - {include "../components/post/oldpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} - {/if} -
- {/foreach} +
+ {if $microblog} + {include "../components/post/microblogpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} + {else} + {include "../components/post/oldpost.xml", post => $post, commentSection => false, suggestion => true, forceNoCommentsLink => true, forceNoPinLink => true, forceNoLike => true, forceNoShareLink => true, forceNoDeleteLink => false} + {/if} +
{include "../components/paginator.xml", conf => (object) [ "page" => $page, From 77fe2fb63e91e077324b2c3d014bfd65e010dc13 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 20 Aug 2023 15:38:21 +0300 Subject: [PATCH 27/34] aiaks --- ServiceAPI/Wall.php | 1 + Web/Presenters/templates/@layout.xml | 2 +- Web/Presenters/templates/Group/View.xml | 4 +- Web/Presenters/templates/components/wall.xml | 3 + Web/static/css/main.css | 8 ++ Web/static/js/al_wall.js | 87 ++++++++++++++++++-- 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index e6133497a..7f594e1d1 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -146,6 +146,7 @@ function acceptPost(int $id, bool $sign, string $content, callable $resolve, cal $post->setSuggested(0); $post->setCreated(time()); + $post->setApi_Source_Name(NULL); $post->setFlags($flags); if(mb_strlen($content) > 0) diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index d962253d3..c8730dde9 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -231,7 +231,7 @@ - {$club->getName()} + {ovk_proc_strtr($club->getName(), 14)} diff --git a/Web/Presenters/templates/Group/View.xml b/Web/Presenters/templates/Group/View.xml index 00e4f1934..d5fb2dfb7 100644 --- a/Web/Presenters/templates/Group/View.xml +++ b/Web/Presenters/templates/Group/View.xml @@ -92,11 +92,11 @@ {presenter "openvk!Wall->wallEmbedded", -$club->getId()} diff --git a/Web/Presenters/templates/components/wall.xml b/Web/Presenters/templates/components/wall.xml index 7d205781f..99d9604b9 100644 --- a/Web/Presenters/templates/components/wall.xml +++ b/Web/Presenters/templates/components/wall.xml @@ -7,6 +7,8 @@
+
+
{include "../components/textArea.xml", route => "/wall$owner/makePost", graffiti => true, polls => true, notes => true}
@@ -24,6 +26,7 @@ {/if}
+ {if isset($thisUser) && $thisUser->hasMicroblogEnabled()} diff --git a/Web/static/css/main.css b/Web/static/css/main.css index cdaf83d78..6ff56e8d7 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2727,3 +2727,11 @@ body.article .floating_sidebar, body.article .page_content { padding: 16px 40px 6px 4px !important; } } + +.sugglist a:hover { + text-decoration: underline; +} + +.sugglist a[data-toogled="true"] { + color:black; +} diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index b1ca61171..639603d1a 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -307,7 +307,12 @@ $(document).on("click", "#publish_post", async (e) => { } NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); - document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) + + if(document.getElementById("cound") != null) { + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) + } else { + document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count) + } if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count @@ -323,7 +328,7 @@ $(document).on("click", "#publish_post", async (e) => { e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" } - if(document.querySelectorAll(".post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) { + if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) { loadMoreSuggestedPosts() } }), Function.noop]); @@ -374,7 +379,11 @@ $(document).on("click", "#decline_post", async (e) => { e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" } - document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) + if(document.getElementById("cound") != null) { + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) + } else { + document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post) + } if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post @@ -384,7 +393,7 @@ $(document).on("click", "#decline_post", async (e) => { } } - if(document.querySelectorAll(".post").length < 1 && post > 0 && document.querySelector(".paginator") != null) { + if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null) { loadMoreSuggestedPosts() } }) @@ -392,7 +401,13 @@ $(document).on("click", "#decline_post", async (e) => { function loadMoreSuggestedPosts() { let xhr = new XMLHttpRequest - xhr.open("GET", location.href) + let link = location.href + + if(!link.includes("/suggested")) { + link += "/suggested" + } + + xhr.open("GET", link) xhr.onloadstart = () => { document.getElementById("postz").innerHTML = `` @@ -425,3 +440,65 @@ function loadMoreSuggestedPosts() xhr.send() } + +// нажатие на "x предложенных записей" +$(document).on("click", ".sugglist a", (e) => { + e.preventDefault() + + if(e.currentTarget.getAttribute("data-toogled") == null || e.currentTarget.getAttribute("data-toogled") == "false") { + e.currentTarget.setAttribute("data-toogled", "true") + document.getElementById("underHeader").style.display = "none" + document.querySelector(".insertThere").style.display = "block" + history.pushState({}, "", e.currentTarget.href) + + // если ещё ничего не подгружалось + if(document.querySelector(".insertThere").innerHTML == "") { + let xhr = new XMLHttpRequest + xhr.open("GET", e.currentTarget.href) + + xhr.onloadstart = () => { + // лоадер + document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", ``) + } + + xhr.onload = () => { + let parser = new DOMParser + let result = parser.parseFromString(xhr.responseText, 'text/html').querySelector(".infContainer") + // парсинг результата и вставка постов + document.querySelector(".insertThere").innerHTML = result.innerHTML + } + + xhr.send() + } + } else { + // переключение на нормальную стену + e.currentTarget.setAttribute("data-toogled", "false") + document.getElementById("underHeader").style.display = "block" + document.querySelector(".insertThere").style.display = "none" + history.pushState({}, "", e.currentTarget.href.replace("/suggested", "")) + } +}) + +// нажатие на пагинатор у постов пъедложки +$(document).on("click", "#postz .paginator a", (e) => { + e.preventDefault() + + let xhr = new XMLHttpRequest + xhr.open("GET", e.currentTarget.href) + + xhr.onloadstart = () => { + window.scrollTo({top: 0,behavior: "smooth"}) + // после того как долистали наверх, добавляем лоадер + setTimeout(() => {document.querySelector("#postz").innerHTML = ``}, 500) + } + + xhr.onload = () => { + // опять парс + let result = (new DOMParser).parseFromString(xhr.responseText, "text/html").querySelector(".infContainer") + // опять вставка + document.getElementById("postz").innerHTML = result.innerHTML + history.pushState({}, "", e.currentTarget.href) + } + + xhr.send() +}) \ No newline at end of file From ba771625333e80cd22f408e60d306be0e4be869e Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 21 Aug 2023 12:37:00 +0300 Subject: [PATCH 28/34] al_wall.js -> al_suggestions.js --- Web/Presenters/templates/@layout.xml | 1 + Web/static/css/main.css | 3 +- Web/static/js/al_suggestions.js | 270 +++++++++++++++++++++++++++ Web/static/js/al_wall.js | 239 ------------------------ 4 files changed, 273 insertions(+), 240 deletions(-) create mode 100644 Web/static/js/al_suggestions.js diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml index c8730dde9..577ecddaf 100644 --- a/Web/Presenters/templates/@layout.xml +++ b/Web/Presenters/templates/@layout.xml @@ -389,6 +389,7 @@ {script "js/al_api.js"} {script "js/al_mentions.js"} {script "js/al_polls.js"} + {script "js/al_suggestions.js"} {ifset $thisUser} {script "js/al_notifs.js"} diff --git a/Web/static/css/main.css b/Web/static/css/main.css index 6ff56e8d7..e7e124c70 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2733,5 +2733,6 @@ body.article .floating_sidebar, body.article .page_content { } .sugglist a[data-toogled="true"] { - color:black; + text-decoration: underline; + color:#4a4a4a; } diff --git a/Web/static/js/al_suggestions.js b/Web/static/js/al_suggestions.js new file mode 100644 index 000000000..3d7a2a907 --- /dev/null +++ b/Web/static/js/al_suggestions.js @@ -0,0 +1,270 @@ +// "Опубликовать запись" +$(document).on("click", "#publish_post", async (e) => { + let id = Number(e.currentTarget.dataset.id) + let post; + let body = ` + + + ` + + MessageBox(tr("publishing_suggested_post"), body, [tr("publish"), tr("cancel")], [(async () => { + let id = Number(e.currentTarget.dataset.id) + let post; + + try { + e.currentTarget.classList.add("loaded") + e.currentTarget.setAttribute("value", "") + e.currentTarget.setAttribute("id", "") + post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value) + } catch(ex) { + switch(ex.code) { + case 11: + MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); + break; + case 19: + MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); + break; + case 10: + MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); + break; + case 22: + MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); + break; + default: + MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); + break; + } + + e.currentTarget.setAttribute("value", tr("publish_suggested")) + e.currentTarget.classList.remove("loaded") + e.currentTarget.setAttribute("id", "publish_post") + return 0; + } + + NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); + + if(document.getElementById("cound") != null) { + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) + } else { + document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count) + } + + if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { + document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count + + if(post.new_count < 1) { + u("object a[href='"+location.pathname+"']").remove() + } + } + + if(post.new_count < 1 && document.querySelector(".sugglist") != null) { + $(".sugglist a").click() + $(".sugglist").remove() + } + + if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } else { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } + + if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) { + loadMoreSuggestedPosts() + } + }), Function.noop]); + + document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') + document.querySelector(".ovk-diag-body").style.padding = "9px"; +}) + +// "Отклонить" +$(document).on("click", "#decline_post", async (e) => { + let id = Number(e.currentTarget.dataset.id) + let post; + + try { + e.currentTarget.classList.add("loaded") + e.currentTarget.setAttribute("value", "") + e.currentTarget.setAttribute("id", "") + post = await API.Wall.declinePost(id) + } catch(ex) { + switch(ex.code) { + case 11: + MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); + break; + case 19: + MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); + break; + case 10: + MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); + break; + case 22: + MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); + break; + default: + MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); + break; + } + + e.currentTarget.setAttribute("value", tr("decline_suggested")) + e.currentTarget.setAttribute("id", "decline_post") + e.currentTarget.classList.remove("loaded") + return 0; + } + + //NewNotification(tr("suggestion_succefully_declined"), "", null); + + if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } else { + e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" + } + + if(document.getElementById("cound") != null) { + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) + } else { + document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post) + } + + if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { + document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post + + if(post < 1) { + u("object a[href='"+location.pathname+"']").remove() + } + } + + if(post < 1 && document.querySelector(".sugglist") != null) { + $(".sugglist a").click() + $(".sugglist").remove() + } + + if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null) { + loadMoreSuggestedPosts() + } +}) + +function loadMoreSuggestedPosts() +{ + let xhr = new XMLHttpRequest + let link = location.href + + if(!link.includes("/suggested")) { + link += "/suggested" + } + + xhr.open("GET", link) + + xhr.onloadstart = () => { + document.getElementById("postz").innerHTML = `` + } + + xhr.onload = () => { + let parser = new DOMParser() + let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz") + + if(body.querySelectorAll(".post").length < 1) { + let url = new URL(location.href) + url.searchParams.set("p", url.searchParams.get("p") - 1) + + if(url.searchParams.get("p") < 1) { + return 0; + } + + // OVK AJAX ROUTING ?????????? + history.pushState({}, "", url) + + loadMoreSuggestedPosts() + } + + document.getElementById("postz").innerHTML = body.innerHTML + } + + xhr.onerror = () => { + document.getElementById("postz").innerHTML = tr("error_loading_suggest") + } + + xhr.send() +} + +// нажатие на "x предложенных записей" +$(document).on("click", ".sugglist a", (e) => { + e.preventDefault() + + if(e.currentTarget.getAttribute("data-toogled") == null || e.currentTarget.getAttribute("data-toogled") == "false") { + e.currentTarget.setAttribute("data-toogled", "true") + document.getElementById("underHeader").style.display = "none" + document.querySelector(".insertThere").style.display = "block" + document.querySelector(".insertThere").classList.add("infContainer") + history.pushState({}, "", e.currentTarget.href) + + // если ещё ничего не подгружалось + if(document.querySelector(".insertThere").innerHTML == "") { + let xhr = new XMLHttpRequest + xhr.open("GET", e.currentTarget.href) + + xhr.onloadstart = () => { + // лоадер + document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", ``) + } + + xhr.onload = () => { + let parser = new DOMParser + let result = parser.parseFromString(xhr.responseText, 'text/html').querySelector(".infContainer") + // парсинг результата и вставка постов + document.querySelector(".insertThere").innerHTML = result.innerHTML + } + + function errorl() { + document.getElementById("postz").innerHTML = tr("error_loading_suggest") + } + + xhr.onerror = () => {errorl()} + xhr.ontimeout = () => {errorl()} + + xhr.send() + } + } else { + // переключение на нормальную стену + e.currentTarget.setAttribute("data-toogled", "false") + document.getElementById("underHeader").style.display = "block" + document.querySelector(".insertThere").style.display = "none" + document.querySelector(".insertThere").classList.remove("infContainer") + history.pushState({}, "", e.currentTarget.href.replace("/suggested", "")) + } +}) + +// нажатие на пагинатор у постов пъедложки +$(document).on("click", "#postz .paginator a", (e) => { + e.preventDefault() + + let xhr = new XMLHttpRequest + xhr.open("GET", e.currentTarget.href) + + xhr.onloadstart = () => { + if(document.querySelector(".sugglist") != null) { + document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"}) + } else { + document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"}) + } + // после того как долистали наверх, добавляем лоадер + setTimeout(() => {document.getElementById("postz").innerHTML = ``}, 500) + } + + xhr.onload = () => { + // опять парс + let result = (new DOMParser).parseFromString(xhr.responseText, "text/html").querySelector(".infContainer") + // опять вставка + document.getElementById("postz").innerHTML = result.innerHTML + history.pushState({}, "", e.currentTarget.href) + } + + function errorl() { + document.getElementById("postz").innerHTML = tr("error_loading_suggest") + } + + xhr.onerror = () => {errorl()} + xhr.ontimeout = () => {errorl()} + + xhr.send() +}) diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js index 639603d1a..50e9f4b44 100644 --- a/Web/static/js/al_wall.js +++ b/Web/static/js/al_wall.js @@ -263,242 +263,3 @@ async function showArticle(note_id) { u("body").removeClass("dimmed"); u("body").addClass("article"); } - -$(document).on("click", "#publish_post", async (e) => { - let id = Number(e.currentTarget.dataset.id) - let post; - let body = ` - - - ` - - MessageBox(tr("publishing_suggested_post"), body, [tr("publish"), tr("cancel")], [(async () => { - let id = Number(e.currentTarget.dataset.id) - let post; - - try { - e.currentTarget.classList.add("loaded") - e.currentTarget.setAttribute("value", "") - e.currentTarget.setAttribute("id", "") - post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value) - } catch(ex) { - switch(ex.code) { - case 11: - MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); - break; - case 19: - MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); - break; - case 10: - MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); - break; - case 22: - MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); - break; - default: - MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); - break; - } - - e.currentTarget.setAttribute("value", tr("publish_suggested")) - e.currentTarget.classList.remove("loaded") - e.currentTarget.setAttribute("id", "publish_post") - return 0; - } - - NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); - - if(document.getElementById("cound") != null) { - document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) - } else { - document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count) - } - - if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { - document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count - - if(post.new_count < 1) { - u("object a[href='"+location.pathname+"']").remove() - } - } - - if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } else { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } - - if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) { - loadMoreSuggestedPosts() - } - }), Function.noop]); - - document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') - document.querySelector(".ovk-diag-body").style.padding = "9px"; -}) - -$(document).on("click", "#decline_post", async (e) => { - let id = Number(e.currentTarget.dataset.id) - let post; - - try { - e.currentTarget.classList.add("loaded") - e.currentTarget.setAttribute("value", "") - e.currentTarget.setAttribute("id", "") - post = await API.Wall.declinePost(id) - } catch(ex) { - switch(ex.code) { - case 11: - MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); - break; - case 19: - MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); - break; - case 10: - MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); - break; - case 22: - MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); - break; - default: - MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); - break; - } - - e.currentTarget.setAttribute("value", tr("decline_suggested")) - e.currentTarget.setAttribute("id", "decline_post") - e.currentTarget.classList.remove("loaded") - return 0; - } - - //NewNotification(tr("suggestion_succefully_declined"), "", null); - - if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } else { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } - - if(document.getElementById("cound") != null) { - document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) - } else { - document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post) - } - - if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { - document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post - - if(post < 1) { - u("object a[href='"+location.pathname+"']").remove() - } - } - - if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null) { - loadMoreSuggestedPosts() - } -}) - -function loadMoreSuggestedPosts() -{ - let xhr = new XMLHttpRequest - let link = location.href - - if(!link.includes("/suggested")) { - link += "/suggested" - } - - xhr.open("GET", link) - - xhr.onloadstart = () => { - document.getElementById("postz").innerHTML = `` - } - - xhr.onload = () => { - let parser = new DOMParser() - let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz") - - if(body.querySelectorAll(".post").length < 1) { - let url = new URL(location.href) - url.searchParams.set("p", url.searchParams.get("p") - 1) - - if(url.searchParams.get("p") < 1) { - return 0; - } - - // OVK AJAX ROUTING ?????????? - history.pushState({}, "", url) - - loadMoreSuggestedPosts() - } - - document.getElementById("postz").innerHTML = body.innerHTML - } - - xhr.onerror = () => { - document.getElementById("postz").innerHTML = tr("error_loading_suggest") - } - - xhr.send() -} - -// нажатие на "x предложенных записей" -$(document).on("click", ".sugglist a", (e) => { - e.preventDefault() - - if(e.currentTarget.getAttribute("data-toogled") == null || e.currentTarget.getAttribute("data-toogled") == "false") { - e.currentTarget.setAttribute("data-toogled", "true") - document.getElementById("underHeader").style.display = "none" - document.querySelector(".insertThere").style.display = "block" - history.pushState({}, "", e.currentTarget.href) - - // если ещё ничего не подгружалось - if(document.querySelector(".insertThere").innerHTML == "") { - let xhr = new XMLHttpRequest - xhr.open("GET", e.currentTarget.href) - - xhr.onloadstart = () => { - // лоадер - document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", ``) - } - - xhr.onload = () => { - let parser = new DOMParser - let result = parser.parseFromString(xhr.responseText, 'text/html').querySelector(".infContainer") - // парсинг результата и вставка постов - document.querySelector(".insertThere").innerHTML = result.innerHTML - } - - xhr.send() - } - } else { - // переключение на нормальную стену - e.currentTarget.setAttribute("data-toogled", "false") - document.getElementById("underHeader").style.display = "block" - document.querySelector(".insertThere").style.display = "none" - history.pushState({}, "", e.currentTarget.href.replace("/suggested", "")) - } -}) - -// нажатие на пагинатор у постов пъедложки -$(document).on("click", "#postz .paginator a", (e) => { - e.preventDefault() - - let xhr = new XMLHttpRequest - xhr.open("GET", e.currentTarget.href) - - xhr.onloadstart = () => { - window.scrollTo({top: 0,behavior: "smooth"}) - // после того как долистали наверх, добавляем лоадер - setTimeout(() => {document.querySelector("#postz").innerHTML = ``}, 500) - } - - xhr.onload = () => { - // опять парс - let result = (new DOMParser).parseFromString(xhr.responseText, "text/html").querySelector(".infContainer") - // опять вставка - document.getElementById("postz").innerHTML = result.innerHTML - history.pushState({}, "", e.currentTarget.href) - } - - xhr.send() -}) \ No newline at end of file From 2ddd4544e8b07f177548a9226cf31003d1de4fa4 Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sun, 27 Aug 2023 17:47:10 +0300 Subject: [PATCH 29/34] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20Add?= =?UTF-8?q?=20=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20fading=20=F0=9F=91=A8?= =?UTF-8?q?=E2=80=8D=F0=9F=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Web/static/js/al_suggestions.js | 52 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/Web/static/js/al_suggestions.js b/Web/static/js/al_suggestions.js index 3d7a2a907..4b702cb54 100644 --- a/Web/static/js/al_suggestions.js +++ b/Web/static/js/al_suggestions.js @@ -19,13 +19,13 @@ $(document).on("click", "#publish_post", async (e) => { } catch(ex) { switch(ex.code) { case 11: - MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); + MessageBox(tr("error"), tr("error_accepting_invalid_post"), [tr("ok")], [Function.noop]); break; case 19: - MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); + MessageBox(tr("error"), tr("error_accepting_not_suggested_post"), [tr("ok")], [Function.noop]); break; case 10: - MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); + MessageBox(tr("error"), tr("error_accepting_declined_post"), [tr("ok")], [Function.noop]); break; case 22: MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); @@ -43,11 +43,10 @@ $(document).on("click", "#publish_post", async (e) => { NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); - if(document.getElementById("cound") != null) { + if(document.getElementById("cound") != null) document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) - } else { + else document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count) - } if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count @@ -62,18 +61,18 @@ $(document).on("click", "#publish_post", async (e) => { $(".sugglist").remove() } - if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } else { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } - - if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) { + let post_node = e.currentTarget.closest("table") + post_node.style.transition = "opacity 300ms ease-in-out"; + post_node.style.opacity = "0"; + post_node.classList.remove("post") + + setTimeout(() => {post_node.outerHTML = ""}, 300) + + if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) loadMoreSuggestedPosts() - } }), Function.noop]); - document.getElementById("pooblish").innerHTML = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') + document.getElementById("pooblish").innerHTML = e.currentTarget.closest("table").querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') document.querySelector(".ovk-diag-body").style.padding = "9px"; }) @@ -114,18 +113,18 @@ $(document).on("click", "#decline_post", async (e) => { //NewNotification(tr("suggestion_succefully_declined"), "", null); - if(e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.tagName == "TABLE") { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } else { - e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.outerHTML = "" - } + let post_node = e.currentTarget.closest("table") + post_node.style.transition = "opacity 300ms ease-in-out"; + post_node.style.opacity = "0"; + post_node.classList.remove("post") + + setTimeout(() => {post_node.outerHTML = ""}, 300) - if(document.getElementById("cound") != null) { + if(document.getElementById("cound") != null) document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) - } else { + else document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post) - } - + if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post @@ -138,10 +137,9 @@ $(document).on("click", "#decline_post", async (e) => { $(".sugglist a").click() $(".sugglist").remove() } - - if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null) { + + if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null) loadMoreSuggestedPosts() - } }) function loadMoreSuggestedPosts() From e1f10353e0cc979aa4dd53bdbb9dc0872707b6ac Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Mon, 28 Aug 2023 18:08:38 +0300 Subject: [PATCH 30/34] Add "owner's posts' and "other's posts" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Давайте рофлить👨‍💻👨‍💻👨‍💻 --- VKAPI/Handlers/Wall.php | 6 ++- Web/Models/Repositories/Posts.php | 60 ++++++++++++++++++++++++++ Web/Presenters/WallPresenter.php | 25 ++++++++++- Web/Presenters/templates/Wall/Wall.xml | 14 +++++- locales/en.strings | 5 +++ locales/ru.strings | 5 +++ 6 files changed, 110 insertions(+), 5 deletions(-) diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index b90ebeac2..cf8e8fcf4 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -49,10 +49,12 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 $cnt = $posts->getPostCountOnUserWall($owner_id); break; case "owner": - $this->fail(42, "Not implemented"); + $iteratorv = $posts->getOwnersPostsFromWall($owner_id, 1, $count, $offset); + $cnt = $posts->getOwnersCountOnUserWall($owner_id); break; case "others": - $this->fail(42, "Not implemented"); + $iteratorv = $posts->getOthersPostsFromWall($owner_id, 1, $count, $offset); + $cnt = $posts->getOthersCountOnUserWall($owner_id); break; case "postponed": $this->fail(42, "Postponed posts are not implemented."); diff --git a/Web/Models/Repositories/Posts.php b/Web/Models/Repositories/Posts.php index 4cde11a59..89ee58eaa 100644 --- a/Web/Models/Repositories/Posts.php +++ b/Web/Models/Repositories/Posts.php @@ -67,6 +67,50 @@ function getPostsFromUsersWall(int $user, int $page = 1, ?int $perPage = NULL, ? foreach($sel as $post) yield new Post($post); } + + function getOwnersPostsFromWall(int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + { + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + $offset ??= $perPage * ($page - 1); + + $sel = $this->posts->where([ + "wall" => $user, + "deleted" => false, + "suggested" => 0, + ]); + + if($user > 0) + $sel->where("owner", $user); + else + $sel->where("flags !=", 0); + + $sel->order("created DESC")->limit($perPage, $offset); + + foreach($sel as $post) + yield new Post($post); + } + + function getOthersPostsFromWall(int $user, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable + { + $perPage ??= OPENVK_DEFAULT_PER_PAGE; + $offset ??= $perPage * ($page - 1); + + $sel = $this->posts->where([ + "wall" => $user, + "deleted" => false, + "suggested" => 0, + ]); + + if($user > 0) + $sel->where("owner !=", $user); + else + $sel->where("flags", 0); + + $sel->order("created DESC")->limit($perPage, $offset); + + foreach($sel as $post) + yield new Post($post); + } function getPostsByHashtag(string $hashtag, int $page = 1, ?int $perPage = NULL): \Traversable { @@ -147,6 +191,22 @@ function getPostCountOnUserWall(int $user): int return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])); } + function getOwnersCountOnUserWall(int $user): int + { + if($user > 0) + return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "owner" => $user])); + else + return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])->where("flags !=", 0)); + } + + function getOthersCountOnUserWall(int $user): int + { + if($user > 0) + return sizeof($this->posts->where(["wall" => $user, "deleted" => 0])->where("owner !=", $user)); + else + return sizeof($this->posts->where(["wall" => $user, "deleted" => 0, "suggested" => 0])->where("flags", 0)); + } + function getSuggestedPosts(int $club, int $page = 1, ?int $perPage = NULL, ?int $offset = NULL): \Traversable { $perPage ??= OPENVK_DEFAULT_PER_PAGE; diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index b8e94298a..9ea184530 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -66,11 +66,32 @@ function renderWall(int $user, bool $embedded = false): void $this->template->oObj = $owner; if($user < 0) $this->template->club = $owner; + + $iterator = NULL; + $count = 0; + $type = $this->queryParam("type") ?? "all"; + + switch($type) { + default: + case "all": + $iterator = $this->posts->getPostsFromUsersWall($user, (int) ($_GET["p"] ?? 1)); + $count = $this->posts->getPostCountOnUserWall($user); + break; + case "owners": + $iterator = $this->posts->getOwnersPostsFromWall($user, (int) ($_GET["p"] ?? 1)); + $count = $this->posts->getOwnersCountOnUserWall($user); + break; + case "others": + $iterator = $this->posts->getOthersPostsFromWall($user, (int) ($_GET["p"] ?? 1)); + $count = $this->posts->getOthersCountOnUserWall($user); + break; + } $this->template->owner = $user; $this->template->canPost = $canPost; - $this->template->count = $this->posts->getPostCountOnUserWall($user); - $this->template->posts = iterator_to_array($this->posts->getPostsFromUsersWall($user, (int) ($_GET["p"] ?? 1))); + $this->template->count = $count; + $this->template->type = $type; + $this->template->posts = iterator_to_array($iterator); $this->template->paginatorConf = (object) [ "count" => $this->template->count, "page" => (int) ($_GET["p"] ?? 1), diff --git a/Web/Presenters/templates/Wall/Wall.xml b/Web/Presenters/templates/Wall/Wall.xml index a9f8845fe..516d5b8f3 100644 --- a/Web/Presenters/templates/Wall/Wall.xml +++ b/Web/Presenters/templates/Wall/Wall.xml @@ -15,7 +15,19 @@ {block content}
-
+ + +
{include "../components/textArea.xml", route => "/wall$owner/makePost"}
diff --git a/locales/en.strings b/locales/en.strings index 9d6cfd51b..f46401334 100644 --- a/locales/en.strings +++ b/locales/en.strings @@ -214,6 +214,11 @@ "reply" = "Reply"; +"all_posts" = "All posts"; +"users_posts" = "Posts by $1"; +"clubs_posts" = "Group's posts"; +"others_posts" = "Others posts"; + /* Friends */ "friends" = "Friends"; diff --git a/locales/ru.strings b/locales/ru.strings index fd464deb1..b882a4b80 100644 --- a/locales/ru.strings +++ b/locales/ru.strings @@ -192,6 +192,11 @@ "graffiti" = "Граффити"; "reply" = "Ответить"; +"all_posts" = "Все записи"; +"users_posts" = "Записи $1"; +"clubs_posts" = "Записи сообщества"; +"others_posts" = "Чужие записи"; + /* Friends */ "friends" = "Друзья"; From 500107fa78aa2270280e16bc28c901b78c66478a Mon Sep 17 00:00:00 2001 From: lalka2016 <99399973+lalka2016@users.noreply.github.com> Date: Sat, 2 Sep 2023 13:10:06 +0300 Subject: [PATCH 31/34] planshet openvk Add tabs for post view, add signer's object in wall get and add person icon in microblog --- VKAPI/Handlers/Wall.php | 8 ++++---- Web/Presenters/templates/Wall/Post.xml | 14 ++++++++++++++ .../templates/components/post/microblogpost.xml | 4 ++-- Web/static/css/main.css | 14 ++++++++++++++ Web/static/img/person.png | Bin 0 -> 265 bytes 5 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 Web/static/img/person.png diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index cf8e8fcf4..f58feebf7 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -201,8 +201,8 @@ function get(int $owner_id, string $domain = "", int $offset = 0, int $count = 3 else $groups[] = $from_id * -1; - /*if($post->isSigned()) - $profiles[] = $post->getOwner(false)->getId();*/ + if($post->isSigned()) + $profiles[] = $post->getOwner(false)->getId(); $attachments = NULL; # free attachments so it will not clone everythingg } @@ -392,8 +392,8 @@ function getById(string $posts, int $extended = 0, string $fields = "", User $us else $groups[] = $from_id * -1; - /*if($post->isSigned()) - $profiles[] = $post->getOwner(false)->getId();*/ + if($post->isSigned()) + $profiles[] = $post->getOwner(false)->getId(); $attachments = NULL; # free attachments so it will not clone everything $repost = NULL; # same diff --git a/Web/Presenters/templates/Wall/Post.xml b/Web/Presenters/templates/Wall/Post.xml index 575c7bba3..a0da7599f 100644 --- a/Web/Presenters/templates/Wall/Post.xml +++ b/Web/Presenters/templates/Wall/Post.xml @@ -14,6 +14,20 @@ {/block} {block content} + {include "../components/post.xml", post => $post, forceNoCommentsLink => TRUE, forceNoDeleteLink => TRUE}
diff --git a/Web/Presenters/templates/components/post/microblogpost.xml b/Web/Presenters/templates/components/post/microblogpost.xml index b5060fcba..a28a7b544 100644 --- a/Web/Presenters/templates/components/post/microblogpost.xml +++ b/Web/Presenters/templates/components/post/microblogpost.xml @@ -80,8 +80,8 @@
{var $actualAuthor = $post->getOwner(false)} - {_author}: - +
+
{$actualAuthor->getCanonicalName()}
diff --git a/Web/static/css/main.css b/Web/static/css/main.css index e7e124c70..540a14e99 100644 --- a/Web/static/css/main.css +++ b/Web/static/css/main.css @@ -2736,3 +2736,17 @@ body.article .floating_sidebar, body.article .page_content { text-decoration: underline; color:#4a4a4a; } + +.authorIcon { + height: 11px; + margin-top: 1px; + width: 10px; + float: left; + background: url("/assets/packages/static/openvk/img/person.png") no-repeat 0 0; +} + +.authorName { + margin-left: 4px; + font-weight: normal !important; + font-size: 11px; +} diff --git a/Web/static/img/person.png b/Web/static/img/person.png new file mode 100644 index 0000000000000000000000000000000000000000..9706c1a1771df7ae8595a0b966138e38262470d3 GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^AT~D#8<2F%laT;YjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!Fir8jv*Ssxf2Ze+7x))xSJ<3Z;)VnoO&bS z`I0#e%oYzg?|4X*JP*%c_*;8<@n5G~LKPd=Wq-QIoXoT3+Sd4^meaT89u9ZpU<^7n zXW`DGjqk0al#g{>V{K1#$PS3Qtt;W=kUi&l=QY;%5AXLp21@iA){DQ$&h6+r3f8>2sDEOF4d8eVJW3?;*R+34M(oVU4Fimoj*|`njxg HN@xNAN4;aR literal 0 HcmV?d00001 From 029d21c7eed961d6ec76932cb89a3d1c5949162d Mon Sep 17 00:00:00 2001 From: lalka2018 <99399973+lalka2016@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:16:48 +0300 Subject: [PATCH 32/34] Simplefai ze kod --- ServiceAPI/Wall.php | 62 ---- Web/Models/Entities/Post.php | 6 + Web/Presenters/InternalAPIPresenter.php | 2 +- Web/Presenters/WallPresenter.php | 91 +++++- Web/routes.yml | 4 + Web/static/js/al_suggestions.js | 371 +++++++++++------------- 6 files changed, 268 insertions(+), 268 deletions(-) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index 467d59fed..f8d9fca2a 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -2,8 +2,6 @@ namespace openvk\ServiceAPI; use openvk\Web\Models\Entities\Post; use openvk\Web\Models\Entities\User; -use openvk\Web\Models\Entities\Notifications\PostAcceptedNotification; -use openvk\Web\Models\Repositories\{Posts, Notes}; use openvk\Web\Models\Repositories\{Posts, Notes, Videos}; class Wall implements Handler @@ -101,67 +99,7 @@ function getMyNotes(callable $resolve, callable $reject) $resolve($arr); } - - function declinePost(int $id, callable $resolve, callable $reject) - { - $post = $this->posts->get($id); - if(!$post || $post->isDeleted()) - $reject(11, "No post with id=$id"); - - if($post->getSuggestionType() == 0) - $reject(19, "Post is not suggested"); - - if($post->getSuggestionType() == 2) - $reject(10, "Post is already declined"); - - if(!$post->canBePinnedBy($this->user)) - $reject(22, "Access to post denied"); - - $post->setSuggested(2); - $post->setDeleted(1); - $post->save(); - - $resolve($this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())); - } - - function acceptPost(int $id, bool $sign, string $content, callable $resolve, callable $reject) - { - $post = $this->posts->get($id); - if(!$post || $post->isDeleted()) - $reject(11, "No post with id=$id"); - - if($post->getSuggestionType() == 0) - $reject(19, "Post is not suggested"); - - if($post->getSuggestionType() == 2) - $reject(10, "Post is declined"); - - if(!$post->canBePinnedBy($this->user)) - $reject(22, "Access to post denied"); - - $author = $post->getOwner(); - $flags = 0; - $flags |= 0b10000000; - - if($sign) - $flags |= 0b01000000; - - $post->setSuggested(0); - $post->setCreated(time()); - $post->setApi_Source_Name(NULL); - $post->setFlags($flags); - - if(mb_strlen($content) > 0) - $post->setContent($content); - - $post->save(); - - if($author->getId() != $this->user->getId()) - (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); - $resolve(["id" => $post->getPrettyId(), "new_count" => $this->posts->getSuggestedPostsCount($post->getWallOwner()->getId())]); - } - function getVideos(int $page = 1, callable $resolve, callable $reject) { $videos = $this->videos->getByUser($this->user, $page, 8); diff --git a/Web/Models/Entities/Post.php b/Web/Models/Entities/Post.php index a43a8b478..a53ede22b 100644 --- a/Web/Models/Entities/Post.php +++ b/Web/Models/Entities/Post.php @@ -264,6 +264,12 @@ function canBeEditedBy(?User $user = NULL): bool if($this->getTargetWall() > 0) return $this->getPublicationTime()->timestamp() + WEEK > time() && $user->getId() == $this->getOwner(false)->getId(); + else { + if($this->isPostedOnBehalfOfGroup()) + return $this->getWallOwner()->canBeModifiedBy($user); + else + return $user->getId() == $this->getOwner(false)->getId(); + } return $user->getId() == $this->getOwner(false)->getId(); } diff --git a/Web/Presenters/InternalAPIPresenter.php b/Web/Presenters/InternalAPIPresenter.php index e2e6b50e9..dca5db042 100644 --- a/Web/Presenters/InternalAPIPresenter.php +++ b/Web/Presenters/InternalAPIPresenter.php @@ -104,7 +104,7 @@ function renderGetPhotosFromPost(int $owner_id, int $post_id) { } if($this->postParam("parentType", false) == "post") { - $post = (new Posts)->getPostById($owner_id, $post_id); + $post = (new Posts)->getPostById($owner_id, $post_id, true); } else { $post = (new Comments)->get($post_id); } diff --git a/Web/Presenters/WallPresenter.php b/Web/Presenters/WallPresenter.php index 39bc86a37..9c7bfaa44 100644 --- a/Web/Presenters/WallPresenter.php +++ b/Web/Presenters/WallPresenter.php @@ -2,7 +2,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, NewSuggestedPostsNotification, RepostNotification, WallPostNotification}; +use openvk\Web\Models\Entities\Notifications\{MentionNotification, NewSuggestedPostsNotification, RepostNotification, WallPostNotification, PostAcceptedNotification}; use openvk\Web\Models\Repositories\{Posts, Users, Clubs, Albums, Notes, Videos, Comments, Photos}; use Chandler\Database\DatabaseConnection; use Nette\InvalidStateException as ISE; @@ -624,4 +624,93 @@ function renderEdit() "avatar" => $post->getOwner()->getAvatarUrl() ]]); } + + function renderAccept() { + $this->assertUserLoggedIn(); + $this->willExecuteWriteAction(true); + + if($_SERVER["REQUEST_METHOD"] !== "POST") { + header("HTTP/1.1 405 Method Not Allowed"); + exit("Ты дебил, это точка апи."); + } + + $id = $this->postParam("id"); + $sign = $this->postParam("sign") == 1; + $content = $this->postParam("new_content"); + + $post = (new Posts)->get((int)$id); + + if(!$post || $post->isDeleted()) + $this->flashFail("err", "Error", tr("error_accepting_invalid_post"), NULL, true); + + if($post->getSuggestionType() == 0) + $this->flashFail("err", "Error", tr("error_accepting_not_suggested_post"), NULL, true); + + if($post->getSuggestionType() == 2) + $this->flashFail("err", "Error", tr("error_accepting_declined_post"), NULL, true); + + if(!$post->canBePinnedBy($this->user->identity)) + $this->flashFail("err", "Error", "Can't accept this post.", NULL, true); + + $author = $post->getOwner(); + + $flags = 0; + $flags |= 0b10000000; + + if($sign) + $flags |= 0b01000000; + + $post->setSuggested(0); + $post->setCreated(time()); + $post->setApi_Source_Name(NULL); + $post->setFlags($flags); + + if(mb_strlen($content) > 0) + $post->setContent($content); + + $post->save(); + + if($author->getId() != $this->user->id) + (new PostAcceptedNotification($author, $post, $post->getWallOwner()))->emit(); + + $this->returnJson([ + "success" => true, + "id" => $post->getPrettyId(), + "new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId()) + ]); + } + + function renderDecline() { + $this->assertUserLoggedIn(); + $this->willExecuteWriteAction(true); + + if($_SERVER["REQUEST_METHOD"] !== "POST") { + header("HTTP/1.1 405 Method Not Allowed"); + exit("Ты дебил, это метод апи."); + } + + $id = $this->postParam("id"); + $post = (new Posts)->get((int)$id); + + if(!$post || $post->isDeleted()) + $this->flashFail("err", "Error", tr("error_declining_invalid_post"), NULL, true); + + if($post->getSuggestionType() == 0) + $this->flashFail("err", "Error", tr("error_declining_not_suggested_post"), NULL, true); + + if($post->getSuggestionType() == 2) + $this->flashFail("err", "Error", tr("error_declining_declined_post"), NULL, true); + + if(!$post->canBePinnedBy($this->user->identity)) + $this->flashFail("err", "Error", "Can't decline this post.", NULL, true); + + $post->setSuggested(2); + $post->setDeleted(1); + $post->save(); + + $this->returnJson([ + "success" => true, + "new_count" => (new Posts)->getSuggestedPostsCount($post->getWallOwner()->getId()) + ]); + } } diff --git a/Web/routes.yml b/Web/routes.yml index 5703fd287..755ec2f31 100644 --- a/Web/routes.yml +++ b/Web/routes.yml @@ -141,6 +141,10 @@ routes: handler: "Wall->delete" - url: "/wall{num}_{num}/pin" handler: "Wall->pin" + - url: "/wall/accept" + handler: "Wall->accept" + - url: "/wall/decline" + handler: "Wall->decline" - url: "/blob_{text}/{?path}.{text}" handler: "Blob->file" placeholders: diff --git a/Web/static/js/al_suggestions.js b/Web/static/js/al_suggestions.js index 4b702cb54..1c3da3e86 100644 --- a/Web/static/js/al_suggestions.js +++ b/Web/static/js/al_suggestions.js @@ -1,3 +1,32 @@ +function endSuggestAction(new_count, post_node) { + if(document.getElementById("cound") != null) + document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", new_count) + else + document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", new_count) + + if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { + document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = new_count + + if(new_count < 1) { + u("object a[href='"+location.pathname+"']").remove() + } + } + + if(new_count < 1 && document.querySelector(".sugglist") != null) { + $(".sugglist a").click() + $(".sugglist").remove() + } + + post_node.style.transition = "opacity 300ms ease-in-out"; + post_node.style.opacity = "0"; + post_node.classList.remove("post") + + setTimeout(() => {post_node.outerHTML = ""}, 300) + + if(document.querySelectorAll("#postz .post").length < 1 && new_count > 0 && document.querySelector(".paginator") != null) + loadMoreSuggestedPosts() +} + // "Опубликовать запись" $(document).on("click", "#publish_post", async (e) => { let id = Number(e.currentTarget.dataset.id) @@ -11,178 +40,122 @@ $(document).on("click", "#publish_post", async (e) => { let id = Number(e.currentTarget.dataset.id) let post; - try { - e.currentTarget.classList.add("loaded") - e.currentTarget.setAttribute("value", "") - e.currentTarget.setAttribute("id", "") - post = await API.Wall.acceptPost(id, document.getElementById("signatr").checked, document.getElementById("pooblish").value) - } catch(ex) { - switch(ex.code) { - case 11: - MessageBox(tr("error"), tr("error_accepting_invalid_post"), [tr("ok")], [Function.noop]); - break; - case 19: - MessageBox(tr("error"), tr("error_accepting_not_suggested_post"), [tr("ok")], [Function.noop]); - break; - case 10: - MessageBox(tr("error"), tr("error_accepting_declined_post"), [tr("ok")], [Function.noop]); - break; - case 22: - MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); - break; - default: - MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); - break; - } - - e.currentTarget.setAttribute("value", tr("publish_suggested")) - e.currentTarget.classList.remove("loaded") - e.currentTarget.setAttribute("id", "publish_post") - return 0; - } - - NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + post.id)}); - - if(document.getElementById("cound") != null) - document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post.new_count) - else - document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post.new_count) - - if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { - document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post.new_count - - if(post.new_count < 1) { - u("object a[href='"+location.pathname+"']").remove() - } - } - - if(post.new_count < 1 && document.querySelector(".sugglist") != null) { - $(".sugglist a").click() - $(".sugglist").remove() - } - - let post_node = e.currentTarget.closest("table") - post_node.style.transition = "opacity 300ms ease-in-out"; - post_node.style.opacity = "0"; - post_node.classList.remove("post") - - setTimeout(() => {post_node.outerHTML = ""}, 300) - - if(document.querySelectorAll("#postz .post").length < 1 && post.new_count > 0 && document.querySelector(".paginator") != null) - loadMoreSuggestedPosts() + let formData = new FormData() + formData.append("id", id) + formData.append("sign", document.getElementById("signatr").checked ? 1 : 0) + formData.append("new_content", document.getElementById("pooblish").value) + formData.append("hash", u("meta[name=csrf]").attr("value")) + + ky.post("/wall/accept", { + hooks: { + beforeRequest: [ + (_request) => { + e.currentTarget.classList.add("loaded") + e.currentTarget.setAttribute("value", "") + e.currentTarget.setAttribute("id", "") + } + ], + afterResponse: [ + async (_request, _options, response) => { + json = await response.json() + + if(json.success) { + NewNotification(tr("suggestion_succefully_published"), tr("suggestion_press_to_go"), null, () => {window.location.assign("/wall" + json.id)}); + endSuggestAction(json.new_count, e.currentTarget.closest("table")) + } else { + MessageBox(tr("error"), json.flash.message, [tr("ok")], [Function.noop]); + } + + e.currentTarget.setAttribute("value", tr("publish_suggested")) + e.currentTarget.classList.remove("loaded") + e.currentTarget.setAttribute("id", "publish_post") + } + ] + }, + body: formData + }) }), Function.noop]); - document.getElementById("pooblish").innerHTML = e.currentTarget.closest("table").querySelector(".really_text").innerHTML.replace(/(<([^>]+)>)/gi, '') + document.getElementById("pooblish").innerHTML = e.currentTarget.closest("table").querySelector(".really_text").dataset.text document.querySelector(".ovk-diag-body").style.padding = "9px"; }) // "Отклонить" $(document).on("click", "#decline_post", async (e) => { let id = Number(e.currentTarget.dataset.id) - let post; - - try { - e.currentTarget.classList.add("loaded") - e.currentTarget.setAttribute("value", "") - e.currentTarget.setAttribute("id", "") - post = await API.Wall.declinePost(id) - } catch(ex) { - switch(ex.code) { - case 11: - MessageBox(tr("error"), tr("error_declining_invalid_post"), [tr("ok")], [Function.noop]); - break; - case 19: - MessageBox(tr("error"), tr("error_declining_not_suggested_post"), [tr("ok")], [Function.noop]); - break; - case 10: - MessageBox(tr("error"), tr("error_declining_declined_post"), [tr("ok")], [Function.noop]); - break; - case 22: - MessageBox(tr("error"), "Access denied", [tr("ok")], [Function.noop]); - break; - default: - MessageBox(tr("error"), "Unknown error "+ex.code+": "+ex.message, [tr("ok")], [Function.noop]); - break; - } - - e.currentTarget.setAttribute("value", tr("decline_suggested")) - e.currentTarget.setAttribute("id", "decline_post") - e.currentTarget.classList.remove("loaded") - return 0; - } - - //NewNotification(tr("suggestion_succefully_declined"), "", null); - - let post_node = e.currentTarget.closest("table") - post_node.style.transition = "opacity 300ms ease-in-out"; - post_node.style.opacity = "0"; - post_node.classList.remove("post") - setTimeout(() => {post_node.outerHTML = ""}, 300) - - if(document.getElementById("cound") != null) - document.getElementById("cound").innerHTML = tr("suggested_posts_in_group", post) - else - document.getElementById("cound_r").innerHTML = tr("suggested_by_everyone", post) - - if(document.querySelector("object a[href='"+location.pathname+"'] b") != null) { - document.querySelector("object a[href='"+location.pathname+"'] b").innerHTML = post - - if(post < 1) { - u("object a[href='"+location.pathname+"']").remove() - } - } - - if(post < 1 && document.querySelector(".sugglist") != null) { - $(".sugglist a").click() - $(".sugglist").remove() - } - - if(document.querySelectorAll("#postz .post").length < 1 && post > 0 && document.querySelector(".paginator") != null) - loadMoreSuggestedPosts() + let formData = new FormData() + formData.append("id", id) + formData.append("hash", u("meta[name=csrf]").attr("value")) + + ky.post("/wall/decline", { + hooks: { + beforeRequest: [ + (_request) => { + e.currentTarget.classList.add("loaded") + e.currentTarget.setAttribute("value", "") + e.currentTarget.setAttribute("id", "") + } + ], + afterResponse: [ + async (_request, _options, response) => { + json = await response.json() + + if(json.success) { + endSuggestAction(json.new_count, e.currentTarget.closest("table")) + } else { + MessageBox(tr("error"), json.flash.message, [tr("ok")], [Function.noop]); + } + + e.currentTarget.setAttribute("value", tr("decline_suggested")) + e.currentTarget.setAttribute("id", "decline_post") + e.currentTarget.classList.remove("loaded") + } + ] + }, + body: formData + }) }) -function loadMoreSuggestedPosts() -{ - let xhr = new XMLHttpRequest +function loadMoreSuggestedPosts() { let link = location.href if(!link.includes("/suggested")) { link += "/suggested" } - xhr.open("GET", link) - - xhr.onloadstart = () => { - document.getElementById("postz").innerHTML = `` - } - - xhr.onload = () => { - let parser = new DOMParser() - let body = parser.parseFromString(xhr.responseText, "text/html").getElementById("postz") - - if(body.querySelectorAll(".post").length < 1) { - let url = new URL(location.href) - url.searchParams.set("p", url.searchParams.get("p") - 1) - - if(url.searchParams.get("p") < 1) { - return 0; - } + ky.get(link, { + hooks: { + beforeRequest: [ + (_request) => { + document.getElementById("postz").innerHTML = `` + } + ], + afterResponse: [ + async (_request, _options, response) => { + let text = await response.text() + let parser = new DOMParser() + let body = parser.parseFromString(text, "text/html") + + if(body.querySelectorAll(".post").length < 1) { + let url = new URL(location.href) + url.searchParams.set("p", url.searchParams.get("p") - 1) + + if(url.searchParams.get("p") < 1) { + return 0; + } - // OVK AJAX ROUTING ?????????? - history.pushState({}, "", url) + history.pushState({}, "", url) + + loadMoreSuggestedPosts() + } - loadMoreSuggestedPosts() + body.querySelectorAll(".bsdn").forEach(bsdnInitElement) + document.getElementById("postz").innerHTML = body.getElementById("postz").innerHTML + } + ] } - - document.getElementById("postz").innerHTML = body.innerHTML - } - - xhr.onerror = () => { - document.getElementById("postz").innerHTML = tr("error_loading_suggest") - } - - xhr.send() + }) } // нажатие на "x предложенных записей" @@ -198,29 +171,24 @@ $(document).on("click", ".sugglist a", (e) => { // если ещё ничего не подгружалось if(document.querySelector(".insertThere").innerHTML == "") { - let xhr = new XMLHttpRequest - xhr.open("GET", e.currentTarget.href) - - xhr.onloadstart = () => { - // лоадер - document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", ``) - } - - xhr.onload = () => { - let parser = new DOMParser - let result = parser.parseFromString(xhr.responseText, 'text/html').querySelector(".infContainer") - // парсинг результата и вставка постов - document.querySelector(".insertThere").innerHTML = result.innerHTML - } - - function errorl() { - document.getElementById("postz").innerHTML = tr("error_loading_suggest") - } - - xhr.onerror = () => {errorl()} - xhr.ontimeout = () => {errorl()} - - xhr.send() + ky(e.currentTarget.href, { + hooks: { + beforeRequest: [ + (_request) => { + document.querySelector(".insertThere").insertAdjacentHTML("afterbegin", ``) + } + ], + afterResponse: [ + async (_request, _options, response) => { + let parser = new DOMParser + let result = parser.parseFromString(await response.text(), 'text/html').querySelector(".infContainer") + + result.querySelectorAll(".bsdn").forEach(bsdnInitElement) + document.querySelector(".insertThere").innerHTML = result.innerHTML + } + ] + } + }) } } else { // переключение на нормальную стену @@ -232,37 +200,32 @@ $(document).on("click", ".sugglist a", (e) => { } }) -// нажатие на пагинатор у постов пъедложки +// нажатие на пагинатор у постов предложки $(document).on("click", "#postz .paginator a", (e) => { e.preventDefault() - let xhr = new XMLHttpRequest - xhr.open("GET", e.currentTarget.href) - - xhr.onloadstart = () => { - if(document.querySelector(".sugglist") != null) { - document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"}) - } else { - document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"}) + ky(e.currentTarget.href, { + hooks: { + beforeRequest: [ + (_request) => { + if(document.querySelector(".sugglist") != null) { + document.querySelector(".sugglist").scrollIntoView({behavior: "smooth"}) + } else { + document.querySelector(".infContainer").scrollIntoView({behavior: "smooth"}) + } + + setTimeout(() => {document.getElementById("postz").innerHTML = ``}, 500) + } + ], + afterResponse: [ + async (_request, _options, response) => { + let result = (new DOMParser).parseFromString(await response.text(), "text/html").querySelector(".infContainer") + result.querySelectorAll(".bsdn").forEach(bsdnInitElement) + + document.getElementById("postz").innerHTML = result.innerHTML + history.pushState({}, "", e.currentTarget.href) + } + ] } - // после того как долистали наверх, добавляем лоадер - setTimeout(() => {document.getElementById("postz").innerHTML = ``}, 500) - } - - xhr.onload = () => { - // опять парс - let result = (new DOMParser).parseFromString(xhr.responseText, "text/html").querySelector(".infContainer") - // опять вставка - document.getElementById("postz").innerHTML = result.innerHTML - history.pushState({}, "", e.currentTarget.href) - } - - function errorl() { - document.getElementById("postz").innerHTML = tr("error_loading_suggest") - } - - xhr.onerror = () => {errorl()} - xhr.ontimeout = () => {errorl()} - - xhr.send() + }) }) From 029ce27e419c6badb80b30ac497765915e5dad37 Mon Sep 17 00:00:00 2001 From: lalka2018 <99399973+lalka2016@users.noreply.github.com> Date: Wed, 15 Nov 2023 22:41:18 +0300 Subject: [PATCH 33/34] PHP 8 FIX WATAFAK --- ServiceAPI/Wall.php | 2 +- Web/Presenters/GroupPresenter.php | 4 ++-- .../sqls/{00039-suggest-posts.sql => 00043-suggest-posts.sql} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename install/sqls/{00039-suggest-posts.sql => 00043-suggest-posts.sql} (100%) diff --git a/ServiceAPI/Wall.php b/ServiceAPI/Wall.php index f8d9fca2a..06d7353ce 100644 --- a/ServiceAPI/Wall.php +++ b/ServiceAPI/Wall.php @@ -132,7 +132,7 @@ function searchVideos(int $page = 1, string $query, callable $resolve, callable ]; foreach($videos as $video) { - $res = json_decode(json_encode($video->toVkApiStruct()), true); + $res = json_decode(json_encode($video->toVkApiStruct($this->user)), true); $res["video"]["author_name"] = $video->getOwner()->getCanonicalName(); $arr["items"][] = $res; diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php index 6c89ea259..beeede139 100644 --- a/Web/Presenters/GroupPresenter.php +++ b/Web/Presenters/GroupPresenter.php @@ -448,11 +448,11 @@ function renderSuggested(int $id): void } if(!$club->canBeModifiedBy($this->user->identity)) { - $this->template->posts = (new Posts)->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1)); + $this->template->posts = iterator_to_array((new Posts)->getSuggestedPostsByUser($club->getId(), $this->user->id, (int) ($this->queryParam("p") ?? 1))); $this->template->count = (new Posts)->getSuggestedPostsCountByUser($club->getId(), $this->user->id); $this->template->type = "my"; } else { - $this->template->posts = (new Posts)->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1)); + $this->template->posts = iterator_to_array((new Posts)->getSuggestedPosts($club->getId(), (int) ($this->queryParam("p") ?? 1))); $this->template->count = (new Posts)->getSuggestedPostsCount($club->getId()); $this->template->type = "everyone"; } diff --git a/install/sqls/00039-suggest-posts.sql b/install/sqls/00043-suggest-posts.sql similarity index 100% rename from install/sqls/00039-suggest-posts.sql rename to install/sqls/00043-suggest-posts.sql From 2cc1b03cd1748516b70d55d3ba63ddbfb010c75b Mon Sep 17 00:00:00 2001 From: lalka2018 <99399973+lalka2016@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:07:13 +0300 Subject: [PATCH 34/34] Add indesk --- install/sqls/00043-suggest-posts.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/sqls/00043-suggest-posts.sql b/install/sqls/00043-suggest-posts.sql index 2437c5e2a..1188f5599 100644 --- a/install/sqls/00043-suggest-posts.sql +++ b/install/sqls/00043-suggest-posts.sql @@ -1 +1 @@ -ALTER TABLE `posts` ADD `suggested` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `deleted`; +ALTER TABLE `posts` ADD `suggested` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `deleted`, ADD INDEX (`suggested`);