diff options
Diffstat (limited to 'Digitigrade')
| -rw-r--r-- | Digitigrade/Model/Actor.php | 44 | ||||
| -rw-r--r-- | Digitigrade/Notification/AdminEditedNoteNotif.php | 9 | ||||
| -rw-r--r-- | Digitigrade/Notification/PokeNotif.php | 62 | ||||
| -rw-r--r-- | Digitigrade/PokeVerb.php | 14 |
4 files changed, 123 insertions, 6 deletions
diff --git a/Digitigrade/Model/Actor.php b/Digitigrade/Model/Actor.php index 0541e1b..18aba15 100644 --- a/Digitigrade/Model/Actor.php +++ b/Digitigrade/Model/Actor.php @@ -3,12 +3,16 @@ namespace Digitigrade\Model; use Digitigrade\Db; use Digitigrade\Notification\PendingFollowActionedNotif; +use Digitigrade\Notification\PokeNotif; use Digitigrade\Notification\UnblockNotif; use Digitigrade\Notification\UnfollowNotif; +use Digitigrade\PokeVerb; use Digitigrade\RpcException; use Digitigrade\RpcReceiver; class Actor extends PushableModel implements RpcReceiver { + public const EXTENSION_POKE = 'https://pawpub.entities.org.uk/extension/poke'; + public ?int $id; public string $uri; public bool $isLocal = false; @@ -135,15 +139,15 @@ class Actor extends PushableModel implements RpcReceiver { return self::findByUri($uri); } - public function rpcCall(string $method, array $args) { - // $args = [Actor $actingAs] + public function rpcCall(string $method, array $args, string $customEndpoint = null) { + // $args = [Actor $actingAs, ?string $requestBody] if (!$this->isLocal) { // trigger the same action on the remote server - $endpoint = $this->endpoints->{$method} ?? null; + $endpoint = $customEndpoint ?? $this->endpoints->{$method} ?? null; if (!isset($endpoint)) { throw new RpcException("Actor `$this->uri` has no $method endpoint"); } - $result = send_request_authenticated($endpoint, method: 'POST', actingAs: $args[0]); + $result = send_request_authenticated($endpoint, method: 'POST', actingAs: $args[0], body: $args[1] ?? null); if (!str_contains($result->headers[0], ' 20')) { throw new RpcException('remote call did not indicate success: ' . $result->headers[0]); } @@ -188,6 +192,16 @@ class Actor extends PushableModel implements RpcReceiver { (new UnblockNotif($args[0], $this))->processNotifications(); return; + case 'poke': + $obj = json_decode($args[1] ?? ''); + (new PokeNotif( + $args[0], + PokeVerb::tryFrom($obj?->verb ?? '') ?? PokeVerb::POKE, + $this, + $obj?->urgent ?? false + ))->processNotifications(); + return; + default: throw new \RuntimeException("behaviour for actor rpc method $method not (yet?) implemented"); } @@ -329,6 +343,25 @@ class Actor extends PushableModel implements RpcReceiver { return '/@/' . $this->getFullHandle(); } + private function getPokeEndpoint(): ?string { + return $this->extensions[self::EXTENSION_POKE] ?? null; + } + + public function poke(self $target, PokeVerb $verb = PokeVerb::POKE, bool $urgent = false) { + $target->rpcCall('poke', [$this, json_encode([ + 'verb' => $verb->value, + 'urgent' => $urgent + ])], $target->getPokeEndpoint()); + } + + public function isPokeable(): bool { + return isset($this->extensions[self::EXTENSION_POKE]); + } + + public function setPokeable(bool $pokeable) { + $this->extensions[self::EXTENSION_POKE] = $pokeable ? path_to_uri("/actor/$this->id/poke") : null; + } + public function jsonSerialize(): array { if ($this->deleted) { return [ @@ -359,7 +392,8 @@ class Actor extends PushableModel implements RpcReceiver { 'rejectedFollow' => path_to_uri("/actor/$this->id/rejectedFollow"), 'block' => path_to_uri("/actor/$this->id/block"), 'unblock' => path_to_uri("/actor/$this->id/unblock"), - ] + ], + 'extensions' => $this->extensions ]; } } diff --git a/Digitigrade/Notification/AdminEditedNoteNotif.php b/Digitigrade/Notification/AdminEditedNoteNotif.php index f3c18a1..888130b 100644 --- a/Digitigrade/Notification/AdminEditedNoteNotif.php +++ b/Digitigrade/Notification/AdminEditedNoteNotif.php @@ -2,6 +2,7 @@ namespace Digitigrade\Notification; use Digitigrade\Model\Note; +use Digitigrade\Model\Notification; use Digitigrade\Model\UserAccount; class AdminEditedNoteNotif implements Notifyable { @@ -22,7 +23,7 @@ class AdminEditedNoteNotif implements Notifyable { } public function getNotificationTitle(): string { - return __f('notification.adminEditedNote', $this->admin->actor->displayName); + return __f('notifications.adminEditedNote', $this->admin->actor->displayName); } public function getNotificationTitleLink(): ?string { @@ -40,4 +41,10 @@ class AdminEditedNoteNotif implements Notifyable { public function getNotificationImageLink(): ?string { return $this->admin->actor->getLocalUiHref(); } + + public function processNotifications() { + if (!$this->note->author->isLocal) + return; + Notification::fromNotifyable($this, UserAccount::findByLinkedActor($this->note->author))->send(); + } }
\ No newline at end of file diff --git a/Digitigrade/Notification/PokeNotif.php b/Digitigrade/Notification/PokeNotif.php new file mode 100644 index 0000000..5446098 --- /dev/null +++ b/Digitigrade/Notification/PokeNotif.php @@ -0,0 +1,62 @@ +<?php +namespace Digitigrade\Notification; + +use Digitigrade\Model\Actor; +use Digitigrade\Model\Notification; +use Digitigrade\Model\UserAccount; +use Digitigrade\PokeVerb; + +class PokeNotif implements Notifyable { + private Actor $subject; + private PokeVerb $verb; + private Actor $object; + private bool $urgent; + + public function __construct(Actor $subject, PokeVerb $verb, Actor $object, bool $urgent) { + $this->subject = $subject; + $this->verb = $verb; + $this->object = $object; + $this->urgent = $urgent; + } + + public function toJsonReference(): mixed { + return [$this->subject->id, $this->verb->value, $this->object->id, $this->urgent]; + } + + public static function fromJsonReference(mixed $reference): ?self { + return new self( + Actor::find($reference[0]), + PokeVerb::from($reference[1]), + Actor::find($reference[2]), + $reference[3] + ); + } + + public function getNotificationTitle(): string { + $kind = $this->urgent ? 'urgent' : 'normal'; + $verb = $this->verb->value; + return __f("notifications.poke.$kind", $this->subject->displayName, __("notifications.poke.verb.$verb")); + } + + public function getNotificationTitleLink(): ?string { + return $this->subject->getLocalUiHref(); + } + + public function getNotificationBody(): ?string { + return null; + } + + public function getNotificationImageUrl(): ?string { + return $this->subject->avatar ?? '/static/default-avatar.png'; + } + + public function getNotificationImageLink(): ?string { + return $this->subject->getLocalUiHref(); + } + + 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/PokeVerb.php b/Digitigrade/PokeVerb.php new file mode 100644 index 0000000..6490b78 --- /dev/null +++ b/Digitigrade/PokeVerb.php @@ -0,0 +1,14 @@ +<?php +namespace Digitigrade; + +enum PokeVerb: string { + case POKE = 'poke'; + case BITE = 'bite'; + case PUNCH = 'punch'; + case KICK = 'kick'; + case WAVE = 'wave'; + case YELL = 'yell'; + case HUG = 'hug'; + case KISS = 'kiss'; + case PET = 'pet'; +}
\ No newline at end of file |
