diff --git a/extensions/sticky/bootstrap.php b/extensions/sticky/bootstrap.php index f09cac86c..0afa317f8 100644 --- a/extensions/sticky/bootstrap.php +++ b/extensions/sticky/bootstrap.php @@ -1,9 +1,5 @@ app->register('Flarum\Sticky\StickyServiceProvider'); +return 'Flarum\Sticky\Extension'; diff --git a/extensions/sticky/js/Gulpfile.js b/extensions/sticky/js/Gulpfile.js index fae866679..f015c1647 100644 --- a/extensions/sticky/js/Gulpfile.js +++ b/extensions/sticky/js/Gulpfile.js @@ -1,5 +1,5 @@ var gulp = require('flarum-gulp'); gulp({ - modulePrefix: 'flarum-sticky' + modulePrefix: 'sticky' }); diff --git a/extensions/sticky/js/bootstrap.js b/extensions/sticky/js/bootstrap.js deleted file mode 100644 index f5baf754d..000000000 --- a/extensions/sticky/js/bootstrap.js +++ /dev/null @@ -1,81 +0,0 @@ -import { extend } from 'flarum/extension-utils'; -import Model from 'flarum/model'; -import Discussion from 'flarum/models/discussion'; -import DiscussionPage from 'flarum/components/discussion-page'; -import DiscussionList from 'flarum/components/discussion-list'; -import DiscussionListItem from 'flarum/components/discussion-list-item'; -import Badge from 'flarum/components/badge'; -import ActionButton from 'flarum/components/action-button'; -import SettingsPage from 'flarum/components/settings-page'; -import icon from 'flarum/helpers/icon'; -import truncate from 'flarum/utils/truncate'; -import app from 'flarum/app'; - -import DiscussionStickiedPost from 'flarum-sticky/components/discussion-stickied-post'; -import DiscussionStickiedNotification from 'flarum-sticky/components/discussion-stickied-notification'; - -app.initializers.add('sticky', function() { - - // Register components. - app.postComponentRegistry['discussionStickied'] = DiscussionStickiedPost; - app.notificationComponentRegistry['discussionStickied'] = DiscussionStickiedNotification; - - Discussion.prototype.isSticky = Model.prop('isSticky'); - Discussion.prototype.canSticky = Model.prop('canSticky'); - - // Add a sticky badge to discussions. - extend(Discussion.prototype, 'badges', function(badges) { - if (this.isSticky()) { - badges.add('sticky', Badge.component({ - label: 'Sticky', - icon: 'thumb-tack', - className: 'badge-sticky', - }), {last: true}); - } - }); - - function toggleSticky() { - this.save({isSticky: !this.isSticky()}).then(discussion => { - if (app.current instanceof DiscussionPage) { - app.current.stream.sync(); - } - m.redraw(); - }); - } - - // Add a sticky control to discussions. - extend(Discussion.prototype, 'moderationControls', function(items) { - if (this.canSticky()) { - items.add('sticky', ActionButton.component({ - label: this.isSticky() ? 'Unsticky' : 'Sticky', - icon: 'thumb-tack', - onclick: toggleSticky.bind(this) - })); - } - }); - - // Add a notification preference. - extend(SettingsPage.prototype, 'notificationTypes', function(items) { - items.add('discussionStickied', { - name: 'discussionStickied', - label: [icon('thumb-tack'), ' Someone stickies a discussion I started'] - }, {after: 'discussionRenamed'}); - }); - - extend(DiscussionList.prototype, 'params', function(params) { - params.include.push('startPost'); - }); - - extend(DiscussionListItem.prototype, 'infoItems', function(items) { - var discussion = this.props.discussion; - - if (discussion.isSticky()) { - var startPost = discussion.startPost(); - if (startPost) { - var excerpt = m('span', truncate(startPost.contentPlain(), 200)); - excerpt.wrapperClass = 'discussion-excerpt'; - items.add('excerpt', excerpt, {last: true}); - } - } - }); -}); diff --git a/extensions/sticky/js/src/addStickyBadge.js b/extensions/sticky/js/src/addStickyBadge.js new file mode 100644 index 000000000..1566c3434 --- /dev/null +++ b/extensions/sticky/js/src/addStickyBadge.js @@ -0,0 +1,15 @@ +import { extend } from 'flarum/extend'; +import Discussion from 'flarum/models/Discussion'; +import Badge from 'flarum/components/Badge'; + +export default function addStickyBadge() { + extend(Discussion.prototype, 'badges', function(badges) { + if (this.isSticky()) { + badges.add('sticky', Badge.component({ + type: 'sticky', + label: app.trans('sticky.stickied'), + icon: 'thumb-tack' + }), 10); + } + }); +} diff --git a/extensions/sticky/js/src/addStickyControl.js b/extensions/sticky/js/src/addStickyControl.js new file mode 100644 index 000000000..e7651fd23 --- /dev/null +++ b/extensions/sticky/js/src/addStickyControl.js @@ -0,0 +1,26 @@ +import { extend } from 'flarum/extend'; +import DiscussionControls from 'flarum/utils/DiscussionControls'; +import DiscussionPage from 'flarum/components/DiscussionPage'; +import Button from 'flarum/components/Button'; + +export default function addStickyControl() { + extend(DiscussionControls, 'moderationControls', function(items, discussion) { + if (discussion.canSticky()) { + items.add('sticky', Button.component({ + children: app.trans(discussion.isSticky() ? 'sticky.unsticky' : 'sticky.sticky'), + icon: 'thumb-tack', + onclick: this.stickyAction.bind(discussion) + })); + } + }); + + DiscussionControls.stickyAction = function() { + this.save({isSticky: !this.isSticky()}).then(() => { + if (app.current instanceof DiscussionPage) { + app.current.stream.update(); + } + + m.redraw(); + }); + }; +} diff --git a/extensions/sticky/js/src/addStickyExcerpt.js b/extensions/sticky/js/src/addStickyExcerpt.js new file mode 100644 index 000000000..932f748d5 --- /dev/null +++ b/extensions/sticky/js/src/addStickyExcerpt.js @@ -0,0 +1,24 @@ +import { extend } from 'flarum/extend'; +import DiscussionList from 'flarum/components/DiscussionList'; +import DiscussionListItem from 'flarum/components/DiscussionListItem'; +import { truncate } from 'flarum/utils/string'; + +export default function addStickyControl() { + extend(DiscussionList.prototype, 'requestParams', function(params) { + params.include.push('startPost'); + }); + + extend(DiscussionListItem.prototype, 'infoItems', function(items) { + const discussion = this.props.discussion; + + if (discussion.isSticky()) { + const startPost = discussion.startPost(); + + if (startPost) { + const excerpt = {truncate(startPost.contentPlain(), 200)}; + + items.add('excerpt', excerpt, 100); + } + } + }); +} diff --git a/extensions/sticky/js/src/components/DiscussionStickiedNotification.js b/extensions/sticky/js/src/components/DiscussionStickiedNotification.js new file mode 100644 index 000000000..b1dc64217 --- /dev/null +++ b/extensions/sticky/js/src/components/DiscussionStickiedNotification.js @@ -0,0 +1,15 @@ +import Notification from 'flarum/components/Notification'; + +export default class DiscussionStickiedNotification extends Notification { + icon() { + return 'thumb-tack'; + } + + href() { + return app.route.discussion(notification.subject(), notification.content().postNumber); + } + + content() { + return app.trans('sticky.discussion_stickied_notification', {user: this.props.notification.sender()}); + } +} diff --git a/extensions/sticky/js/src/components/DiscussionStickiedPost.js b/extensions/sticky/js/src/components/DiscussionStickiedPost.js new file mode 100644 index 000000000..5b3408e69 --- /dev/null +++ b/extensions/sticky/js/src/components/DiscussionStickiedPost.js @@ -0,0 +1,13 @@ +import EventPost from 'flarum/components/EventPost'; + +export default class DiscussionStickiedPost extends EventPost { + icon() { + return 'thumb-tack'; + } + + descriptionKey() { + return this.props.post.content().sticky + ? 'sticky.discussion_stickied_post' + : 'sticky.discussion_unstickied_post'; + } +} diff --git a/extensions/sticky/js/src/components/discussion-stickied-notification.js b/extensions/sticky/js/src/components/discussion-stickied-notification.js deleted file mode 100644 index 81f636e19..000000000 --- a/extensions/sticky/js/src/components/discussion-stickied-notification.js +++ /dev/null @@ -1,14 +0,0 @@ -import Notification from 'flarum/components/notification'; -import username from 'flarum/helpers/username'; - -export default class DiscussionStickiedNotification extends Notification { - view() { - var notification = this.props.notification; - - return super.view({ - href: app.route.discussion(notification.subject(), notification.content().postNumber), - icon: 'thumb-tack', - content: [username(notification.sender()), ' stickied'] - }); - } -} diff --git a/extensions/sticky/js/src/components/discussion-stickied-post.js b/extensions/sticky/js/src/components/discussion-stickied-post.js deleted file mode 100644 index 3d8e786a4..000000000 --- a/extensions/sticky/js/src/components/discussion-stickied-post.js +++ /dev/null @@ -1,9 +0,0 @@ -import EventPost from 'flarum/components/event-post'; - -export default class DiscussionStickiedPost extends EventPost { - view() { - var post = this.props.post; - - return super.view('thumb-tack', [post.content().sticky ? 'stickied' : 'unstickied', ' the discussion.']); - } -} diff --git a/extensions/sticky/js/src/main.js b/extensions/sticky/js/src/main.js new file mode 100644 index 000000000..655a9b09d --- /dev/null +++ b/extensions/sticky/js/src/main.js @@ -0,0 +1,29 @@ +import { extend, notificationType } from 'flarum/extend'; +import app from 'flarum/app'; +import Model from 'flarum/Model'; +import Discussion from 'flarum/models/Discussion'; +import NotificationGrid from 'flarum/components/NotificationGrid'; + +import DiscussionStickiedPost from 'sticky/components/DiscussionStickiedPost'; +import DiscussionStickiedNotification from 'sticky/components/DiscussionStickiedNotification'; +import addStickyBadge from 'sticky/addStickyBadge'; +import addStickyControl from 'sticky/addStickyControl'; +import addStickyExcerpt from 'sticky/addStickyExcerpt'; + +app.postComponents.discussionStickied = DiscussionStickiedPost; +app.notificationComponents.discussionStickied = DiscussionStickiedNotification; + +Discussion.prototype.isSticky = Model.attribute('isSticky'); +Discussion.prototype.canSticky = Model.attribute('canSticky'); + +addStickyBadge(); +addStickyControl(); +addStickyExcerpt(); + +extend(NotificationGrid.prototype, 'notificationTypes', function(items) { + items.add('discussionStickied', { + name: 'discussionStickied', + icon: 'thumb-tack', + label: app.trans('sticky.notify_discussion_stickied') + }); +}); diff --git a/extensions/sticky/less/extension.less b/extensions/sticky/less/extension.less new file mode 100644 index 000000000..046da8ed5 --- /dev/null +++ b/extensions/sticky/less/extension.less @@ -0,0 +1,26 @@ +.Badge--sticky { + background: #d13e32; +} +.DiscussionStickiedPost { + & .EventPost-icon, + & .EventPost-info, + & .EventPost-info a { + color: #d13e32; + } +} +.DiscussionListItem-info .item-excerpt { + margin-top: 8px; + margin-right: 20px; + white-space: normal; + font-size: 12px; + line-height: 1.5em; + color: @muted-more-color; + display: block; + + .DiscussionPage-list & { + display: none; + } + @media @phone { + display: none; + } +} diff --git a/extensions/sticky/less/sticky.less b/extensions/sticky/less/sticky.less deleted file mode 100644 index cc7456d96..000000000 --- a/extensions/sticky/less/sticky.less +++ /dev/null @@ -1,27 +0,0 @@ -.badge-sticky { - background: #d13e32; -} -.discussion-stickied-post { - & .post-icon, & .event-post-info, & .event-post-info a { - color: #d13e32; - } -} -.discussion-excerpt { - margin-top: 8px; - margin-right: 20px; - white-space: normal; - font-size: 12px; - line-height: 1.5em; - color: @fl-body-muted-more-color; - - .discussion-summary .info > li& { - display: block; - - .paned & { - display: none; - } - @media @phone { - display: none; - } - } -} diff --git a/extensions/sticky/locale/en.yml b/extensions/sticky/locale/en.yml new file mode 100644 index 000000000..b871de0d5 --- /dev/null +++ b/extensions/sticky/locale/en.yml @@ -0,0 +1,8 @@ +sticky: + discussion_stickied_notification: "{username} stickied" + discussion_stickied_post: "{username} stickied the discussion." + discussion_unstickied_post: "{username} unstickied the discussion." + notify_discussion_stickied: Someone stickies a discussion I started + stickied: Sticky + sticky: Sticky + unsticky: Unsticky diff --git a/extensions/sticky/src/Events/DiscussionWasStickied.php b/extensions/sticky/src/Events/DiscussionWasStickied.php index 31432f4aa..f1747a406 100644 --- a/extensions/sticky/src/Events/DiscussionWasStickied.php +++ b/extensions/sticky/src/Events/DiscussionWasStickied.php @@ -1,23 +1,23 @@ subscribe('Flarum\Sticky\Listeners\AddClientAssets'); + $events->subscribe('Flarum\Sticky\Listeners\AddApiAttributes'); + $events->subscribe('Flarum\Sticky\Listeners\PersistData'); + $events->subscribe('Flarum\Sticky\Listeners\PinStickiedDiscussionsToTop'); + $events->subscribe('Flarum\Sticky\Listeners\NotifyDiscussionStickied'); + } +} diff --git a/extensions/sticky/src/StickyGambit.php b/extensions/sticky/src/Gambits/StickyGambit.php similarity index 56% rename from extensions/sticky/src/StickyGambit.php rename to extensions/sticky/src/Gambits/StickyGambit.php index 7dd2262d5..2915ad1b9 100644 --- a/extensions/sticky/src/StickyGambit.php +++ b/extensions/sticky/src/Gambits/StickyGambit.php @@ -1,9 +1,9 @@ -getQuery()->where('is_sticky', ! $negate); + $search->getQuery()->where('is_sticky', ! $negate); } } diff --git a/extensions/sticky/src/Handlers/DiscussionStickiedNotifier.php b/extensions/sticky/src/Handlers/DiscussionStickiedNotifier.php deleted file mode 100755 index c36c5a97a..000000000 --- a/extensions/sticky/src/Handlers/DiscussionStickiedNotifier.php +++ /dev/null @@ -1,58 +0,0 @@ -notifications = $notifications; - } - - /** - * Register the listeners for the subscriber. - * - * @param \Illuminate\Contracts\Events\Dispatcher $events - */ - public function subscribe(Dispatcher $events) - { - $events->listen('Flarum\Sticky\Events\DiscussionWasStickied', __CLASS__.'@whenDiscussionWasStickied'); - $events->listen('Flarum\Sticky\Events\DiscussionWasUnstickied', __CLASS__.'@whenDiscussionWasUnstickied'); - } - - public function whenDiscussionWasStickied(DiscussionWasStickied $event) - { - $this->stickyChanged($event->discussion, $event->user, true); - } - - public function whenDiscussionWasUnstickied(DiscussionWasUnstickied $event) - { - $this->stickyChanged($event->discussion, $event->user, false); - } - - protected function stickyChanged(Discussion $discussion, User $user, $isSticky) - { - $post = DiscussionStickiedPost::reply( - $discussion->id, - $user->id, - $isSticky - ); - - $post = $discussion->addPost($post); - - if ($discussion->start_user_id !== $user->id) { - $notification = new DiscussionStickiedNotification($post); - - $this->notifications->sync($notification, $post->exists ? [$discussion->startUser] : []); - } - } -} diff --git a/extensions/sticky/src/Listeners/AddApiAttributes.php b/extensions/sticky/src/Listeners/AddApiAttributes.php new file mode 100755 index 000000000..c3597275c --- /dev/null +++ b/extensions/sticky/src/Listeners/AddApiAttributes.php @@ -0,0 +1,30 @@ +listen(ApiAttributes::class, __CLASS__.'@addAttributes'); + $events->listen(BuildApiAction::class, __CLASS__.'@includeStartPost'); + } + + public function addAttributes(ApiAttributes $event) + { + if ($event->serializer instanceof DiscussionSerializer) { + $event->attributes['isSticky'] = (bool) $event->model->is_sticky; + $event->attributes['canSticky'] = (bool) $event->model->can($event->actor, 'sticky'); + } + } + public function includeStartPost(BuildApiAction $event) + { + if ($event->action instanceof DiscussionsIndexAction) { + $event->addInclude('startPost'); + } + } +} diff --git a/extensions/sticky/src/Listeners/AddClientAssets.php b/extensions/sticky/src/Listeners/AddClientAssets.php new file mode 100755 index 000000000..0d5d8d3bb --- /dev/null +++ b/extensions/sticky/src/Listeners/AddClientAssets.php @@ -0,0 +1,39 @@ +listen(RegisterLocales::class, __CLASS__.'@addLocale'); + $events->listen(BuildClientView::class, __CLASS__.'@addAssets'); + } + + public function addLocale(RegisterLocales $event) + { + $event->addTranslations('en', __DIR__.'/../../locale/en.yml'); + } + + public function addAssets(BuildClientView $event) + { + $event->forumAssets([ + __DIR__.'/../../js/dist/extension.js', + __DIR__.'/../../less/extension.less' + ]); + + $event->forumBootstrapper('sticky/main'); + + $event->forumTranslations([ + 'sticky.discussion_stickied_notification', + 'sticky.discussion_stickied_post', + 'sticky.discussion_unstickied_post', + 'sticky.notify_discussion_stickied', + 'sticky.stickied', + 'sticky.sticky', + 'sticky.unsticky' + ]); + } +} diff --git a/extensions/sticky/src/Listeners/NotifyDiscussionStickied.php b/extensions/sticky/src/Listeners/NotifyDiscussionStickied.php new file mode 100755 index 000000000..15eb094ab --- /dev/null +++ b/extensions/sticky/src/Listeners/NotifyDiscussionStickied.php @@ -0,0 +1,71 @@ +notifications = $notifications; + } + + public function subscribe(Dispatcher $events) + { + $events->listen(RegisterPostTypes::class, __CLASS__.'@registerPostType'); + $events->listen(RegisterNotificationTypes::class, __CLASS__.'@registerNotificationType'); + $events->listen(DiscussionWasStickied::class, __CLASS__.'@whenDiscussionWasStickied'); + $events->listen(DiscussionWasUnstickied::class, __CLASS__.'@whenDiscussionWasUnstickied'); + } + + public function registerPostType(RegisterPostTypes $event) + { + $event->register('Flarum\Sticky\Posts\DiscussionStickiedPost'); + } + + public function registerNotificationType(RegisterNotificationTypes $event) + { + $event->register( + 'Flarum\Sticky\Notifications\DiscussionStickiedBlueprint', + 'Flarum\Api\Serializers\DiscussionBasicSerializer', + ['alert'] + ); + } + + public function whenDiscussionWasStickied(DiscussionWasStickied $event) + { + $this->stickyChanged($event->discussion, $event->user, true); + } + + public function whenDiscussionWasUnstickied(DiscussionWasUnstickied $event) + { + $this->stickyChanged($event->discussion, $event->user, false); + } + + protected function stickyChanged(Discussion $discussion, User $user, $isSticky) + { + $post = DiscussionStickiedPost::reply( + $discussion->id, + $user->id, + $isSticky + ); + + $post = $discussion->mergePost($post); + + if ($discussion->start_user_id !== $user->id) { + $notification = new DiscussionStickiedBlueprint($post); + + $this->notifications->sync($notification, $post->exists ? [$discussion->startUser] : []); + } + } +} diff --git a/extensions/sticky/src/Handlers/StickySaver.php b/extensions/sticky/src/Listeners/PersistData.php similarity index 54% rename from extensions/sticky/src/Handlers/StickySaver.php rename to extensions/sticky/src/Listeners/PersistData.php index d01da961c..c434bd6b6 100755 --- a/extensions/sticky/src/Handlers/StickySaver.php +++ b/extensions/sticky/src/Listeners/PersistData.php @@ -1,24 +1,24 @@ -listen('Flarum\Core\Events\DiscussionWillBeSaved', __CLASS__.'@whenDiscussionWillBeSaved'); + $events->listen(DiscussionWillBeSaved::class, __CLASS__.'@whenDiscussionWillBeSaved'); } public function whenDiscussionWillBeSaved(DiscussionWillBeSaved $event) { - if (isset($event->command->data['isSticky'])) { - $isSticky = (bool) $event->command->data['isSticky']; + if (isset($event->data['attributes']['isSticky'])) { + $isSticky = (bool) $event->data['attributes']['isSticky']; $discussion = $event->discussion; - $user = $event->command->user; + $actor = $event->actor; - $discussion->assertCan($user, 'sticky'); + $discussion->assertCan($actor, 'sticky'); if ((bool) $discussion->is_sticky === $isSticky) { return; @@ -28,8 +28,8 @@ class StickySaver $discussion->raise( $discussion->is_sticky - ? new DiscussionWasStickied($discussion, $user) - : new DiscussionWasUnstickied($discussion, $user) + ? new DiscussionWasStickied($discussion, $actor) + : new DiscussionWasUnstickied($discussion, $actor) ); } } diff --git a/extensions/sticky/src/Handlers/StickySearchModifier.php b/extensions/sticky/src/Listeners/PinStickiedDiscussionsToTop.php similarity index 55% rename from extensions/sticky/src/Handlers/StickySearchModifier.php rename to extensions/sticky/src/Listeners/PinStickiedDiscussionsToTop.php index 021a17cc2..ce3e236a6 100755 --- a/extensions/sticky/src/Handlers/StickySearchModifier.php +++ b/extensions/sticky/src/Listeners/PinStickiedDiscussionsToTop.php @@ -1,25 +1,33 @@ -listen('Flarum\Core\Events\DiscussionSearchWillBePerformed', __CLASS__.'@reorderSearch'); + $events->listen(RegisterDiscussionGambits::class, __CLASS__.'@registerStickyGambit'); + $events->listen(DiscussionSearchWillBePerformed::class, __CLASS__.'@reorderSearch'); + } + + public function registerStickyGambit(RegisterDiscussionGambits $event) + { + $event->gambits->add('Flarum\Sticky\Gambits\StickyGambit'); } public function reorderSearch(DiscussionSearchWillBePerformed $event) { if ($event->criteria->sort === null) { - $query = $event->searcher->getQuery(); + $query = $event->search->getQuery(); - if (!is_array($query->orders)) { + if (! is_array($query->orders)) { $query->orders = []; } - foreach ($event->searcher->getActiveGambits() as $gambit) { + foreach ($event->search->getActiveGambits() as $gambit) { if ($gambit instanceof TagGambit) { array_unshift($query->orders, ['column' => 'is_sticky', 'direction' => 'desc']); return; @@ -29,7 +37,7 @@ class StickySearchModifier $query->leftJoin('users_discussions', function ($join) use ($event) { $join->on('users_discussions.discussion_id', '=', 'discussions.id') ->where('discussions.is_sticky', '=', true) - ->where('users_discussions.user_id', '=', $event->criteria->user->id); + ->where('users_discussions.user_id', '=', $event->search->getActor()->id); }); // might be quicker to do a subquery in the order clause than a join? array_unshift( diff --git a/extensions/sticky/src/DiscussionStickiedNotification.php b/extensions/sticky/src/Notifications/DiscussionStickiedBlueprint.php similarity index 73% rename from extensions/sticky/src/DiscussionStickiedNotification.php rename to extensions/sticky/src/Notifications/DiscussionStickiedBlueprint.php index b9ff17b0b..3fa44c4c5 100644 --- a/extensions/sticky/src/DiscussionStickiedNotification.php +++ b/extensions/sticky/src/Notifications/DiscussionStickiedBlueprint.php @@ -1,8 +1,8 @@ -post = $post; } - public function getSubject() - { - return $this->post->discussion; - } - public function getSender() { return $this->post->user; } + public function getSubject() + { + return $this->post->discussion; + } + public function getData() { return ['postNumber' => (int) $this->post->number]; @@ -33,6 +33,6 @@ class DiscussionStickiedNotification extends NotificationAbstract public static function getSubjectModel() { - return 'Flarum\Core\Models\Discussion'; + return 'Flarum\Core\Discussions\Discussion'; } } diff --git a/extensions/sticky/src/DiscussionStickiedPost.php b/extensions/sticky/src/Posts/DiscussionStickiedPost.php similarity index 56% rename from extensions/sticky/src/DiscussionStickiedPost.php rename to extensions/sticky/src/Posts/DiscussionStickiedPost.php index 5d94bd947..9af84f4c2 100755 --- a/extensions/sticky/src/DiscussionStickiedPost.php +++ b/extensions/sticky/src/Posts/DiscussionStickiedPost.php @@ -1,35 +1,33 @@ -user_id === $previous->user_id) { + // If the previous post is another 'discussion stickied' post, and it's + // by the same user, then we can merge this post into it. If we find + // that we've in fact reverted the sticky status, delete it. Otherwise, + // update its content. + if ($previous instanceof static && $this->user_id === $previous->user_id) { if ($previous->content['sticky'] != $this->content['sticky']) { - return; + $previous->delete(); + } else { + $previous->content = $this->content; + + $previous->save(); } - $previous->content = $this->content; return $previous; } + $this->save(); + return $this; } diff --git a/extensions/sticky/src/StickyServiceProvider.php b/extensions/sticky/src/StickyServiceProvider.php deleted file mode 100644 index ca2fa685e..000000000 --- a/extensions/sticky/src/StickyServiceProvider.php +++ /dev/null @@ -1,41 +0,0 @@ -extend( - new Extend\EventSubscriber([ - 'Flarum\Sticky\Handlers\StickySaver', - 'Flarum\Sticky\Handlers\StickySearchModifier', - 'Flarum\Sticky\Handlers\DiscussionStickiedNotifier' - ]), - - (new Extend\ForumClient()) - ->assets([ - __DIR__.'/../js/dist/extension.js', - __DIR__.'/../less/sticky.less' - ]), - - new Extend\PostType('Flarum\Sticky\DiscussionStickiedPost'), - - (new Extend\ApiSerializer('Flarum\Api\Serializers\DiscussionSerializer')) - ->attributes(function (&$attributes, $model, $user) { - $attributes['isSticky'] = (bool) $model->is_sticky; - $attributes['canSticky'] = (bool) $model->can($user, 'sticky'); - }), - - // include discussion start posts by default - (new Extend\ApiAction('Flarum\Api\Actions\Discussions\IndexAction')) - ->addInclude('startPost'), - - new Extend\DiscussionGambit('Flarum\Sticky\StickyGambit'), - - (new Extend\NotificationType('Flarum\Sticky\DiscussionStickiedNotification', 'Flarum\Api\Serializers\DiscussionBasicSerializer')) - ->enableByDefault('alert') - ); - } -}