You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
4.1 KiB
107 lines
4.1 KiB
<?php |
|
|
|
declare(strict_types=1); |
|
|
|
namespace App\Controller; |
|
|
|
use App\Service\NostrClient; |
|
use App\Service\NostrLinkParser; |
|
use App\Service\CacheService; |
|
use Exception; |
|
use nostriphant\NIP19\Bech32; |
|
use nostriphant\NIP19\Data; |
|
use Psr\Log\LoggerInterface; |
|
use swentel\nostr\Key\Key; |
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
|
use Symfony\Component\HttpFoundation\Response; |
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
|
use Symfony\Component\Routing\Attribute\Route; |
|
|
|
class EventController extends AbstractController |
|
{ |
|
/** |
|
* @throws Exception |
|
*/ |
|
#[Route('/e/{nevent}', name: 'nevent', requirements: ['nevent' => '^nevent1.*'])] |
|
public function index($nevent, NostrClient $nostrClient, CacheService $cacheService, NostrLinkParser $nostrLinkParser, LoggerInterface $logger): Response |
|
{ |
|
$logger->info('Accessing event page', ['nevent' => $nevent]); |
|
|
|
try { |
|
// Decode nevent - nevent1... is a NIP-19 encoded event identifier |
|
$decoded = new Bech32($nevent); |
|
$logger->info('Decoded event', ['decoded' => json_encode($decoded)]); |
|
|
|
// Get the event using the event ID |
|
/** @var Data $data */ |
|
$data = $decoded->data; |
|
$logger->info('Event data', ['data' => json_encode($data)]); |
|
|
|
// Sort which event type this is using $data->type |
|
switch ($decoded->type) { |
|
case 'note': |
|
// Handle note (regular event) |
|
$relays = $data->relays ?? []; |
|
$event = $nostrClient->getEventById($data->identifier, $relays); |
|
break; |
|
|
|
case 'nprofile': |
|
// Redirect to author profile if it's a profile identifier |
|
$logger->info('Redirecting to author profile', ['pubkey' => $data->pubkey]); |
|
return $this->redirectToRoute('author-redirect', ['pubkey' => $data->pubkey]); |
|
|
|
case 'nevent': |
|
// Handle nevent identifier (event with additional metadata) |
|
$relays = $data->relays ?? []; |
|
$event = $nostrClient->getEventById($data->id, $relays); |
|
break; |
|
|
|
case 'naddr': |
|
// Handle naddr (parameterized replaceable event) |
|
$decodedData = [ |
|
'kind' => $data->kind, |
|
'pubkey' => $data->pubkey, |
|
'identifier' => $data->identifier, |
|
'relays' => $data->relays ?? [] |
|
]; |
|
$event = $nostrClient->getEventByNaddr($decodedData); |
|
break; |
|
|
|
default: |
|
$logger->error('Unsupported event type', ['type' => $decoded->type]); |
|
throw new NotFoundHttpException('Unsupported event type: ' . $decoded->type); |
|
} |
|
|
|
if (!$event) { |
|
$logger->warning('Event not found', ['data' => $data]); |
|
throw new NotFoundHttpException('Event not found'); |
|
} |
|
|
|
// Parse event content for Nostr links |
|
$nostrLinks = []; |
|
if (isset($event->content)) { |
|
$nostrLinks = $nostrLinkParser->parseLinks($event->content); |
|
$logger->info('Parsed Nostr links from content', ['count' => count($nostrLinks)]); |
|
} |
|
|
|
// If author is included in the event, get metadata |
|
$authorMetadata = null; |
|
if (isset($event->pubkey)) { |
|
$key = new Key(); |
|
$npub = $key->convertPublicKeyToBech32($event->pubkey); |
|
$authorMetadata = $cacheService->getMetadata($npub); |
|
} |
|
|
|
// Render template with the event data and extracted Nostr links |
|
return $this->render('event/index.html.twig', [ |
|
'event' => $event, |
|
'author' => $authorMetadata, |
|
'nostrLinks' => $nostrLinks |
|
]); |
|
|
|
} catch (Exception $e) { |
|
$logger->error('Error processing event', ['error' => $e->getMessage()]); |
|
throw $e; |
|
} |
|
} |
|
}
|
|
|