diff --git a/extensions/subscriptions/extend.php b/extensions/subscriptions/extend.php
index 8bb29b5440..f563b6b81f 100644
--- a/extensions/subscriptions/extend.php
+++ b/extensions/subscriptions/extend.php
@@ -10,6 +10,7 @@
use Flarum\Api\Resource;
use Flarum\Approval\Event\PostWasApproved;
use Flarum\Discussion\Event\Saving;
+use Flarum\Discussion\Event\Started;
use Flarum\Discussion\Search\DiscussionSearcher;
use Flarum\Discussion\UserState;
use Flarum\Extend;
@@ -60,7 +61,8 @@
->listen(Hidden::class, Listener\DeleteNotificationWhenPostIsHiddenOrDeleted::class)
->listen(Restored::class, Listener\RestoreNotificationWhenPostIsRestored::class)
->listen(Deleted::class, Listener\DeleteNotificationWhenPostIsHiddenOrDeleted::class)
- ->listen(Posted::class, Listener\FollowAfterReply::class),
+ ->listen(Posted::class, Listener\FollowAfterReply::class)
+ ->listen(Started::class, Listener\FollowAfterCreate::class),
(new Extend\SearchDriver(DatabaseSearchDriver::class))
->addFilter(DiscussionSearcher::class, SubscriptionFilter::class)
@@ -68,5 +70,6 @@
(new Extend\User())
->registerPreference('followAfterReply', 'boolval', false)
+ ->registerPreference('followAfterCreate', 'boolval', false)
->registerPreference('flarum-subscriptions.notify_for_all_posts', 'boolval', false),
];
diff --git a/extensions/subscriptions/js/src/@types/shims.d.ts b/extensions/subscriptions/js/src/@types/shims.d.ts
index 057f872464..c166382259 100644
--- a/extensions/subscriptions/js/src/@types/shims.d.ts
+++ b/extensions/subscriptions/js/src/@types/shims.d.ts
@@ -1,7 +1,16 @@
import 'flarum/common/models/Discussion';
+import 'flarum/forum/components/SettingsPage';
declare module 'flarum/common/models/Discussion' {
export default interface Discussion {
subscription(): string;
}
}
+
+declare module 'flarum/forum/components/SettingsPage' {
+ export default interface SettingsPage {
+ followAfterReplyLoading: boolean;
+ followAfterCreateLoading: boolean;
+ notifyForAllPostsLoading: boolean;
+ }
+}
diff --git a/extensions/subscriptions/js/src/forum/addSubscriptionSettings.tsx b/extensions/subscriptions/js/src/forum/addSubscriptionSettings.tsx
index e5cd93f790..5dc59df832 100644
--- a/extensions/subscriptions/js/src/forum/addSubscriptionSettings.tsx
+++ b/extensions/subscriptions/js/src/forum/addSubscriptionSettings.tsx
@@ -8,7 +8,7 @@ export default function () {
items.add(
'followAfterReply',
{
this.followAfterReplyLoading = true;
@@ -23,6 +23,24 @@ export default function () {
);
+ items.add(
+ 'followAfterCreate',
+ {
+ this.followAfterCreateLoading = true;
+
+ this.user!.savePreferences({ followAfterCreate: value }).then(() => {
+ this.followAfterCreateLoading = false;
+ m.redraw();
+ });
+ }}
+ loading={this.followAfterCreateLoading}
+ >
+ {app.translator.trans('flarum-subscriptions.forum.settings.follow_after_create_label')}
+
+ );
+
items.add(
'notifyForAllPosts',
actor;
+
+ if ($actor && $actor->exists && $actor->getPreference('followAfterCreate')) {
+ $actor->assertRegistered();
+
+ $state = $event->discussion->stateFor($actor);
+
+ $state->subscription = 'follow';
+ $state->save();
+ }
+ }
+}
diff --git a/extensions/subscriptions/tests/integration/api/discussions/FollowAfterCreateTest.php b/extensions/subscriptions/tests/integration/api/discussions/FollowAfterCreateTest.php
new file mode 100644
index 0000000000..f88d7deff0
--- /dev/null
+++ b/extensions/subscriptions/tests/integration/api/discussions/FollowAfterCreateTest.php
@@ -0,0 +1,89 @@
+extension('flarum-subscriptions');
+
+ $this->prepareDatabase([
+ User::class => [
+ $this->normalUser(),
+ ['id' => 3, 'username' => 'acme_follow', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1, 'preferences' => json_encode(['followAfterCreate' => true])],
+ ['id' => 4, 'username' => 'acme_no_follow', 'email' => 'acme2@machine.local', 'is_email_confirmed' => 1, 'preferences' => json_encode(['followAfterCreate' => false])],
+ ],
+ ]);
+ }
+
+ #[Test]
+ public function user_with_preference_true_follows_after_creating_discussion()
+ {
+ $this->app();
+
+ $response = $this->send(
+ $this->request('POST', '/api/discussions', [
+ 'authenticatedAs' => 3,
+ 'json' => [
+ 'data' => [
+ 'type' => 'discussions',
+ 'attributes' => [
+ 'title' => 'Test Discussion',
+ 'content' => 'Test content that needs to be sufficiently long.'
+ ],
+ ],
+ ],
+ ])
+ );
+
+ $this->assertEquals(201, $response->getStatusCode());
+
+ $discussionId = json_decode($response->getBody()->getContents(), true)['data']['id'];
+
+ $this->assertEquals('follow', $this->database()->table('discussion_user')->where('discussion_id', $discussionId)->where('user_id', 3)->value('subscription'));
+ }
+
+ #[Test]
+ public function user_with_preference_false_does_not_follow_after_creating_discussion()
+ {
+ $this->app();
+
+ $response = $this->send(
+ $this->request('POST', '/api/discussions', [
+ 'authenticatedAs' => 4,
+ 'json' => [
+ 'data' => [
+ 'type' => 'discussions',
+ 'attributes' => [
+ 'title' => 'Test Discussion',
+ 'content' => 'Test content that needs to be sufficiently long.'
+ ],
+ ],
+ ],
+ ])
+ );
+
+ $this->assertEquals(201, $response->getStatusCode());
+
+ $discussionId = json_decode($response->getBody()->getContents(), true)['data']['id'];
+
+ $this->assertNull($this->database()->table('discussion_user')->where('discussion_id', $discussionId)->where('user_id', 4)->value('subscription'));
+ }
+}
diff --git a/extensions/subscriptions/tests/integration/api/discussions/FollowAfterReplyTest.php b/extensions/subscriptions/tests/integration/api/discussions/FollowAfterReplyTest.php
new file mode 100644
index 0000000000..e15902a01c
--- /dev/null
+++ b/extensions/subscriptions/tests/integration/api/discussions/FollowAfterReplyTest.php
@@ -0,0 +1,98 @@
+extension('flarum-subscriptions');
+
+ $this->prepareDatabase([
+ User::class => [
+ $this->normalUser(),
+ ['id' => 3, 'username' => 'acme_follow', 'email' => 'acme@machine.local', 'is_email_confirmed' => 1, 'preferences' => json_encode(['followAfterReply' => true])],
+ ['id' => 4, 'username' => 'acme_no_follow', 'email' => 'acme2@machine.local', 'is_email_confirmed' => 1, 'preferences' => json_encode(['followAfterReply' => false])],
+ ],
+ Discussion::class => [
+ ['id' => 1, 'title' => __CLASS__, 'created_at' => Carbon::now(), 'last_posted_at' => Carbon::now(), 'user_id' => 1, 'first_post_id' => 1, 'comment_count' => 1, 'last_post_number' => 1, 'last_post_id' => 1],
+ ],
+ Post::class => [
+ ['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::createFromDate(1975, 5, 21)->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => 'foo bar
', 'number' => 1],
+ ],
+ ]);
+ }
+
+ #[Test]
+ public function user_with_preference_true_follows_after_replying_to_discussion()
+ {
+ $this->app();
+
+ $response = $this->send(
+ $this->request('POST', '/api/posts', [
+ 'authenticatedAs' => 3,
+ 'json' => [
+ 'data' => [
+ 'type' => 'posts',
+ 'attributes' => [
+ 'content' => 'reply with predetermined content for automated testing'
+ ],
+ 'relationships' => [
+ 'discussion' => ['data' => ['id' => 1]],
+ ],
+ ],
+ ],
+ ])
+ );
+
+ $this->assertEquals(201, $response->getStatusCode());
+
+ $this->assertEquals('follow', $this->database()->table('discussion_user')->where('discussion_id', 1)->where('user_id', 3)->value('subscription'));
+ }
+
+ #[Test]
+ public function user_with_preference_false_does_not_follow_after_replying_to_discussion()
+ {
+ $this->app();
+
+ $response = $this->send(
+ $this->request('POST', '/api/posts', [
+ 'authenticatedAs' => 4,
+ 'json' => [
+ 'data' => [
+ 'type' => 'posts',
+ 'attributes' => [
+ 'content' => 'reply with predetermined content for automated testing'
+ ],
+ 'relationships' => [
+ 'discussion' => ['data' => ['id' => 1]],
+ ],
+ ],
+ ],
+ ])
+ );
+
+ $this->assertEquals(201, $response->getStatusCode());
+
+ $this->assertNull($this->database()->table('discussion_user')->where('discussion_id', 1)->where('user_id', 4)->value('subscription'));
+ }
+}