feat: Refactor mention rendering and generator classes

- Add support for Mastodon username mentions
- Add test for parsing Mastodon usernames in notes
- Modify namespace and class imports for `MentionGenerator` and `MentionRenderer` in `Note.php`
- Rename `ContactMentionGenerator.php` to `MentionGenerator.php`
This commit is contained in:
Jonny Barnes 2023-11-19 17:22:02 +00:00
parent 3817545cf3
commit 05c63b241d
Signed by: jonny
SSH key fingerprint: SHA256:CTuSlns5U7qlD9jqHvtnVmfYV3Zwl2Z7WnJ4/dqOaL8
5 changed files with 55 additions and 31 deletions

View file

@ -8,7 +8,7 @@ use League\CommonMark\Extension\Mention\Generator\MentionGeneratorInterface;
use League\CommonMark\Extension\Mention\Mention;
use League\CommonMark\Node\Inline\AbstractInline;
class ContactMentionGenerator implements MentionGeneratorInterface
class MentionGenerator implements MentionGeneratorInterface
{
public function generateMention(Mention $mention): ?AbstractInline
{

View file

@ -1,24 +0,0 @@
<?php
declare(strict_types=1);
namespace App\CommonMark\Renderers;
use App\Models\Contact;
use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
class ContactMentionRenderer implements NodeRendererInterface
{
public function render(Node $node, ChildNodeRendererInterface $childRenderer): string
{
$contact = Contact::where('nick', $node->getIdentifier())->first();
if ($contact === null) {
return '<a href="https://twitter.com/' . $node->getIdentifier() . '">@' . $node->getIdentifier() . '</a>';
}
return trim(view('templates.mini-hcard', ['contact' => $contact])->render());
}
}

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace App\CommonMark\Renderers;
use App\Models\Contact;
use League\CommonMark\Node\Node;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\CommonMark\Util\HtmlElement;
class MentionRenderer implements NodeRendererInterface
{
public function render(Node $node, ChildNodeRendererInterface $childRenderer): HtmlElement|string
{
$contact = Contact::where('nick', $node->getIdentifier())->first();
// If we have a contact, render a mini-hcard
if ($contact) {
// rendering a blade template to a string, so cant be an HtmlElement
return trim(view('templates.mini-hcard', ['contact' => $contact])->render());
}
// Otherwise, check the link is to the Mastodon profile
$mentionText = $node->getIdentifier();
$parts = explode('@', $mentionText);
// This is not [@]handle@instance, so return a Twitter link
if (count($parts) === 1) {
return new HtmlElement('a', ['href' => 'https://twitter.com/' . $parts[0]], '@' . $mentionText);
}
// Render the Mastodon profile link
return new HtmlElement('a', ['href' => 'https://' . $parts[1] . '/@' . $parts[0]], '@' . $mentionText);
}
}