aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Digitigrade/Model/Actor.php9
-rw-r--r--Digitigrade/Model/FollowRelation.php37
-rw-r--r--Digitigrade/Notification/PendingFollowActionedNotif.php52
-rw-r--r--Digitigrade/Notification/UnfollowNotif.php49
-rw-r--r--locale/en_GB.json5
5 files changed, 150 insertions, 2 deletions
diff --git a/Digitigrade/Model/Actor.php b/Digitigrade/Model/Actor.php
index d04c841..b4e9392 100644
--- a/Digitigrade/Model/Actor.php
+++ b/Digitigrade/Model/Actor.php
@@ -1,6 +1,8 @@
<?php
namespace Digitigrade\Model;
+use Digitigrade\Notification\PendingFollowActionedNotif;
+use Digitigrade\Notification\UnfollowNotif;
use Digitigrade\RpcException;
use Digitigrade\RpcReceiver;
@@ -118,21 +120,26 @@ class Actor extends PushableModel implements RpcReceiver {
switch ($method) {
case 'follow':
$status = $this->requestToFollow ? FollowRelationStatus::PENDING : FollowRelationStatus::ACTIVE;
- FollowRelation::create($args[0], $this, $status);
+ $rel = FollowRelation::create($args[0], $this, $status);
+ $rel->processNotifications();
return $status;
case 'unfollow':
FollowRelation::findByActors($args[0], $this)->remove();
+ (new UnfollowNotif($args[0], $this))->processNotifications();
return;
case 'acceptedFollow':
$rel = FollowRelation::findByActors($this, $args[0]);
$rel->status = FollowRelationStatus::ACTIVE;
$rel->save();
+ $rel->processNotifications();
+ (new PendingFollowActionedNotif($args[0], $this, 'accept'))->processNotifications();
return;
case 'rejectedFollow':
FollowRelation::findByActors($this, $args[0])->remove();
+ (new PendingFollowActionedNotif($args[0], $this, 'reject'))->processNotifications();
return;
default:
diff --git a/Digitigrade/Model/FollowRelation.php b/Digitigrade/Model/FollowRelation.php
index 0af9da5..7cab761 100644
--- a/Digitigrade/Model/FollowRelation.php
+++ b/Digitigrade/Model/FollowRelation.php
@@ -2,8 +2,9 @@
namespace Digitigrade\Model;
use Digitigrade\Model;
+use Digitigrade\Notification\Notifyable;
-class FollowRelation extends Model {
+class FollowRelation extends Model implements Notifyable {
public Actor $subject;
public Actor $object;
public FollowRelationStatus $status;
@@ -48,4 +49,38 @@ class FollowRelation extends Model {
public static function findAllWithObject(Actor $object): array {
return self::findAllWhere('object = ?', [$object->id]);
}
+
+ public function toJsonReference(): mixed {
+ return [$this->subject->id, $this->object->id];
+ }
+
+ public static function fromJsonReference(mixed $reference): self {
+ return self::findByActors(
+ Actor::find($reference[0]),
+ Actor::find($reference[1])
+ );
+ }
+
+ public function getNotificationTitle(): string {
+ $status = $this->status->value;
+ return sprintf(__("notifications.follow.$status"), $this->subject->displayName);
+ }
+ public function getNotificationTitleLink(): ?string {
+ return '/@/' . $this->subject->getFullHandle();
+ }
+ public function getNotificationImageUrl(): ?string {
+ return $this->subject->avatar ?? '/static/default-avatar.png';
+ }
+ public function getNotificationImageLink(): ?string {
+ return $this->getNotificationTitleLink();
+ }
+ public function getNotificationBody(): ?string {
+ return null;
+ }
+
+ public function processNotifications() {
+ if (!$this->object->isLocal)
+ return;
+ Notification::fromNotifyable($this, UserAccount::findByLinkedActor($this->object))->send();
+ }
} \ No newline at end of file
diff --git a/Digitigrade/Notification/PendingFollowActionedNotif.php b/Digitigrade/Notification/PendingFollowActionedNotif.php
new file mode 100644
index 0000000..6ab36ee
--- /dev/null
+++ b/Digitigrade/Notification/PendingFollowActionedNotif.php
@@ -0,0 +1,52 @@
+<?php
+namespace Digitigrade\Notification;
+
+use Digitigrade\Model\Actor;
+use Digitigrade\Model\Notification;
+use Digitigrade\Model\UserAccount;
+
+class PendingFollowActionedNotif implements Notifyable {
+ private Actor $subject;
+ private Actor $object;
+ private string $action;
+
+ public function __construct(Actor $subject, Actor $object, string $action) {
+ $this->subject = $subject;
+ $this->object = $object;
+ $this->action = $action;
+ }
+
+ public function toJsonReference(): mixed {
+ return [$this->subject->id, $this->object->id, $this->action];
+ }
+
+ public static function fromJsonReference(mixed $reference): self {
+ return new self(
+ Actor::find($reference[0]),
+ Actor::find($reference[1]),
+ $reference[2]
+ );
+ }
+
+ public function getNotificationTitle(): string {
+ return sprintf(__("notifications.follow.$this->action"), $this->subject->displayName);
+ }
+ public function getNotificationTitleLink(): ?string {
+ return '/@/' . $this->subject->getFullHandle();
+ }
+ public function getNotificationImageUrl(): ?string {
+ return $this->subject->avatar ?? '/static/default-avatar.png';
+ }
+ public function getNotificationImageLink(): ?string {
+ return $this->getNotificationTitleLink();
+ }
+ public function getNotificationBody(): ?string {
+ return null;
+ }
+
+ public function processNotifications() {
+ if (!$this->object->isLocal)
+ return;
+ Notification::fromNotifyable($this, UserAccount::findByLinkedActor($this->object))->send();
+ }
+} \ No newline at end of file
diff --git a/Digitigrade/Notification/UnfollowNotif.php b/Digitigrade/Notification/UnfollowNotif.php
new file mode 100644
index 0000000..e00c342
--- /dev/null
+++ b/Digitigrade/Notification/UnfollowNotif.php
@@ -0,0 +1,49 @@
+<?php
+namespace Digitigrade\Notification;
+
+use Digitigrade\Model\Actor;
+use Digitigrade\Model\Notification;
+use Digitigrade\Model\UserAccount;
+
+class UnfollowNotif implements Notifyable {
+ private Actor $subject;
+ private Actor $object;
+
+ public function __construct(Actor $subject, Actor $object) {
+ $this->subject = $subject;
+ $this->object = $object;
+ }
+
+ public function toJsonReference(): mixed {
+ return [$this->subject->id, $this->object->id];
+ }
+
+ public static function fromJsonReference(mixed $reference): self {
+ return new self(
+ Actor::find($reference[0]),
+ Actor::find($reference[1])
+ );
+ }
+
+ public function getNotificationTitle(): string {
+ return sprintf(__('notifications.follow.removed'), $this->subject->displayName);
+ }
+ public function getNotificationTitleLink(): ?string {
+ return '/@/' . $this->subject->getFullHandle();
+ }
+ public function getNotificationImageUrl(): ?string {
+ return $this->subject->avatar ?? '/static/default-avatar.png';
+ }
+ public function getNotificationImageLink(): ?string {
+ return $this->getNotificationTitleLink();
+ }
+ public function getNotificationBody(): ?string {
+ return null;
+ }
+
+ public function processNotifications() {
+ if (!$this->object->isLocal)
+ return;
+ Notification::fromNotifyable($this, UserAccount::findByLinkedActor($this->object))->send();
+ }
+} \ No newline at end of file
diff --git a/locale/en_GB.json b/locale/en_GB.json
index 084ecb1..cb4df6a 100644
--- a/locale/en_GB.json
+++ b/locale/en_GB.json
@@ -48,6 +48,11 @@
"notifications.interaction.dislike.title": "%s disliked your note",
"notifications.interaction.reshare.title": "%s reshared your note",
"notifications.interaction.reply.title": "%s replied to you",
+ "notifications.follow.active": "%s followed you",
+ "notifications.follow.pending": "%s would like to follow you",
+ "notifications.follow.removed": "%s unfollowed you",
+ "notifications.follow.accept": "%s accepted your follow request",
+ "notifications.follow.reject": "%s rejected your follow request",
"login.pageTitle": "Log in",
"login.email": "Email address",
"login.password": "Password",