diff --git a/extend.php b/extend.php index 9b2bc9e..143a1c0 100644 --- a/extend.php +++ b/extend.php @@ -115,7 +115,10 @@ }), (new Extend\Settings()) + ->default('fof-gamification.blockedUsers', '') + ->default('fof-gamification.rankAmt', 2) ->default('fof-gamification.firstPostOnly', false) + ->default('fof-gamification.allowSelfVotes', true) ->serializeToForum('fof-gamification.topimage1Url', 'fof-gamification.topimage1_path', function ($value) { return $value ? "/assets/$value" : null; }) @@ -128,11 +131,7 @@ ->serializeToForum('fof-gamification-op-votes-only', 'fof-gamification.firstPostOnly', 'boolVal'), (new Extend\ApiSerializer(Serializer\UserSerializer::class)) - ->attributes(function (Serializer\UserSerializer $serializer, User $user, array $attributes) { - $attributes['points'] = $user->votes; - - return $attributes; - }), + ->attributes(AddUserAttributes::class), (new Extend\ApiSerializer(Serializer\BasicDiscussionSerializer::class)) ->attributes(AddDiscussionData::class), diff --git a/js/src/admin/components/SettingsPage.js b/js/src/admin/components/SettingsPage.js index c0631b1..574715b 100755 --- a/js/src/admin/components/SettingsPage.js +++ b/js/src/admin/components/SettingsPage.js @@ -34,6 +34,7 @@ export default class SettingsPage extends ExtensionPage { 'altPostVotingUi', 'upVotesOnly', 'firstPostOnly', + 'allowSelfVotes', ]; this.ranks = app.store.all('ranks'); @@ -250,8 +251,9 @@ export default class SettingsPage extends ExtensionPage { , @@ -386,6 +388,14 @@ export default class SettingsPage extends ExtensionPage { 20 ); + items.add( + 'allowSelfVotes', + + {app.translator.trans('fof-gamification.admin.page.votes.allow_self_votes')} + , + 10 + ); + return items; } diff --git a/js/src/forum/addNotifications.ts b/js/src/forum/addNotifications.ts index 8df775f..10f7938 100644 --- a/js/src/forum/addNotifications.ts +++ b/js/src/forum/addNotifications.ts @@ -7,7 +7,11 @@ import ItemList from 'flarum/common/utils/ItemList'; export default function addNotifications() { app.notificationComponents.vote = VoteNotification; - extend(NotificationGrid.prototype, 'notificationTypes', function (items: ItemList) { + extend(NotificationGrid.prototype, 'notificationTypes', function (items: ItemList<{ name: string; icon: string; label: any }>) { + const user = app.session?.user; + + if (!user?.canHaveVotingNotifications?.()) return; + items.add('vote', { name: 'vote', icon: 'fas fa-thumbs-up', diff --git a/js/src/forum/index.js b/js/src/forum/index.js index 279f9a0..71df7a4 100755 --- a/js/src/forum/index.js +++ b/js/src/forum/index.js @@ -22,7 +22,7 @@ import addNotifications from './addNotifications'; import addVotersToDiscussionPageSideBar from './addVotersToDiscussionPageSideBar'; import addUpvoteTabToUserProfile from './addUpvoteTabToUserProfile'; -app.initializers.add('fof-gamification', (app) => { +app.initializers.add('fof-gamification', () => { Discussion.prototype.votes = Model.attribute('votes'); Discussion.prototype.hasUpvoted = Model.attribute('hasUpvoted'); Discussion.prototype.hasDownvoted = Model.attribute('hasDownvoted'); @@ -31,6 +31,7 @@ app.initializers.add('fof-gamification', (app) => { User.prototype.points = Model.attribute('points'); User.prototype.ranks = Model.hasMany('ranks'); + User.prototype.canHaveVotingNotifications = Model.attribute('canHaveVotingNotifications'); Post.prototype.upvotes = Model.hasMany('upvotes'); Post.prototype.downvotes = Model.hasMany('downvotes'); diff --git a/resources/locale/en.yml b/resources/locale/en.yml index a7f26fe..48f86f5 100755 --- a/resources/locale/en.yml +++ b/resources/locale/en.yml @@ -48,7 +48,7 @@ fof-gamification: page: rankings: blocked: - placeholder: CDK2020, Ralkage, AngelAvila + placeholder: admin, user1, user2 title: Ignored Users help: These users will not be shown on the ranking page. Usernames should be separated by a comma followed by a space. title: Rankings Page @@ -73,6 +73,7 @@ fof-gamification: icon_help: "Input any Font-Awesome icon that is suffixed with -up and -down. Examples: arrow, thumbs, chevron" upvotes_only: Only allow upvoting first_post_only: Only allow up/down votes in the first post in a discussion + allow_self_votes: Users may vote on their own posts save_settings: Save settings convert: button: Convert likes to upvotes diff --git a/src/Access/PostPolicy.php b/src/Access/PostPolicy.php index b1a6c93..e58f046 100644 --- a/src/Access/PostPolicy.php +++ b/src/Access/PostPolicy.php @@ -30,7 +30,12 @@ public function __construct(SettingsRepositoryInterface $settings) private function isFirstPostOnlyMode(): bool { - return $this->settings->get('fof-gamification.firstPostOnly', false); + return $this->settings->get('fof-gamification.firstPostOnly'); + } + + private function voteForSelfEnabled(): bool + { + return $this->settings->get('fof-gamification.allowSelfVotes'); } public function vote(User $actor, Post $post) @@ -39,6 +44,10 @@ public function vote(User $actor, Post $post) return $this->deny(); } + if ($actor->id === $post->user_id && !$this->voteForSelfEnabled()) { + return $this->deny(); + } + return $actor->can('votePosts', $post->discussion); } diff --git a/src/AddUserAttributes.php b/src/AddUserAttributes.php new file mode 100644 index 0000000..661f514 --- /dev/null +++ b/src/AddUserAttributes.php @@ -0,0 +1,26 @@ +votes; + $attributes['canHaveVotingNotifications'] = $user->hasPermission('discussion.upvote_notifications') || $user->hasPermission('discussion.downvote_notifications'); + + return $attributes; + } +}