Browse Source

Demo page for events, tags and mentions

imwald
Nuša Pukšič 7 months ago
parent
commit
75e6b61514
  1. 17
      src/Controller/EventController.php
  2. 3
      src/Service/NostrClient.php
  3. 101
      templates/event/index.html.twig

17
src/Controller/EventController.php

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Controller; namespace App\Controller;
use App\Service\NostrClient; use App\Service\NostrClient;
use App\Service\NostrLinkParser;
use App\Service\RedisCacheService; use App\Service\RedisCacheService;
use Exception; use Exception;
use nostriphant\NIP19\Bech32; use nostriphant\NIP19\Bech32;
@ -22,7 +23,7 @@ class EventController extends AbstractController
* @throws Exception * @throws Exception
*/ */
#[Route('/e/{nevent}', name: 'nevent', requirements: ['nevent' => '^nevent1.*'])] #[Route('/e/{nevent}', name: 'nevent', requirements: ['nevent' => '^nevent1.*'])]
public function index($nevent, NostrClient $nostrClient, RedisCacheService $redisCacheService, LoggerInterface $logger): Response public function index($nevent, NostrClient $nostrClient, RedisCacheService $redisCacheService, NostrLinkParser $nostrLinkParser, LoggerInterface $logger): Response
{ {
$logger->info('Accessing event page', ['nevent' => $nevent]); $logger->info('Accessing event page', ['nevent' => $nevent]);
@ -76,6 +77,13 @@ class EventController extends AbstractController
throw new NotFoundHttpException('Event not found'); 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 // If author is included in the event, get metadata
$authorMetadata = null; $authorMetadata = null;
if (isset($event->pubkey)) { if (isset($event->pubkey)) {
@ -83,10 +91,12 @@ class EventController extends AbstractController
$npub = $key->convertPublicKeyToBech32($event->pubkey); $npub = $key->convertPublicKeyToBech32($event->pubkey);
$authorMetadata = $redisCacheService->getMetadata($npub); $authorMetadata = $redisCacheService->getMetadata($npub);
} }
// Render template with the event data
// Render template with the event data and extracted Nostr links
return $this->render('event/index.html.twig', [ return $this->render('event/index.html.twig', [
'event' => $event, 'event' => $event,
'author' => $authorMetadata 'author' => $authorMetadata,
'nostrLinks' => $nostrLinks
]); ]);
} catch (Exception $e) { } catch (Exception $e) {
@ -95,4 +105,3 @@ class EventController extends AbstractController
} }
} }
} }

3
src/Service/NostrClient.php

@ -267,7 +267,7 @@ class NostrClient
*/ */
public function getEventById(string $eventId, array $relays = []): ?object public function getEventById(string $eventId, array $relays = []): ?object
{ {
$this->logger->info('Getting event by ID', ['event_id' => $eventId]); $this->logger->info('Getting event by ID', ['event_id' => $eventId, 'relays' => $relays]);
// Use provided relays or default if empty // Use provided relays or default if empty
$relaySet = empty($relays) ? $this->defaultRelaySet : $this->createRelaySet($relays); $relaySet = empty($relays) ? $this->defaultRelaySet : $this->createRelaySet($relays);
@ -281,6 +281,7 @@ class NostrClient
// Process the response // Process the response
$events = $this->processResponse($request->send(), function($event) { $events = $this->processResponse($request->send(), function($event) {
$this->logger->debug('Received event', ['event' => $event]);
return $event; return $event;
}); });

101
templates/event/index.html.twig

@ -27,43 +27,38 @@
<twig:Atoms:Content :content="event.content" /> <twig:Atoms:Content :content="event.content" />
</div> </div>
{% if nostrLinks is defined and nostrLinks|length > 0 %}
<div class="nostr-links">
<h4>Referenced Nostr Links</h4>
<ul class="link-list">
{% for link in nostrLinks %}
<li>
<a href="/e/{{ link.identifier }}">{{ link.identifier }}</a>
<span class="link-type">({{ link.type }})</span>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="event-footer"> <div class="event-footer">
<div class="event-tags"> <div class="event-tags">
{% if event.tags is defined and event.tags|length > 0 %} {% if event.tags is defined and event.tags|length > 0 %}
<h4>Tags:</h4>
<ul> <ul>
{% for tag in event.tags %} {% for tag in event.tags %}
{% if tag[0] != 'e' and tag[0] != 'p' %} <li>
<li> <strong>{{ tag[0] }}:</strong> {{ tag[1] }}
<strong>{{ tag[0] }}:</strong> {{ tag[1] }} {% if tag[2] is defined %}
</li> <span>{{ tag[2] }}</span>
{% endif %} {% endif %}
{% if tag[3] is defined %}
<span>{{ tag[3] }}</span>
{% endif %}
</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %} {% endif %}
</div> </div>
<div class="event-references">
{% if event.tags is defined %}
{% set references = [] %}
{% for tag in event.tags %}
{% if tag[0] == 'e' %}
{% set references = references|merge([tag[1]]) %}
{% endif %}
{% endfor %}
{% if references|length > 0 %}
<h4>References:</h4>
<ul>
{% for ref in references %}
<li>
<a href="{{ path('nevent', {nevent: 'nevent1' ~ ref}) }}">{{ ref|slice(0, 8) }}...</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -78,7 +73,6 @@
padding: 1.5rem; padding: 1.5rem;
background: #fff; background: #fff;
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
} }
.event-header { .event-header {
@ -90,19 +84,6 @@
padding-bottom: 1rem; padding-bottom: 1rem;
} }
.author-info {
display: flex;
align-items: center;
gap: 1rem;
}
.author-picture {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
.event-content { .event-content {
font-size: 1.1rem; font-size: 1.1rem;
line-height: 1.6; line-height: 1.6;
@ -110,6 +91,29 @@
white-space: pre-wrap; white-space: pre-wrap;
} }
.nostr-links {
margin: 1.5rem 0;
padding: 1rem;
background-color: #f9f9f9;
border-radius: 4px;
}
.link-list {
list-style: none;
padding-left: 0;
}
.link-list li {
margin-bottom: 0.5rem;
word-break: break-all;
}
.link-type {
color: #6c757d;
font-size: 0.9rem;
margin-left: 0.5rem;
}
.event-footer { .event-footer {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -118,7 +122,7 @@
border-top: 1px solid #eee; border-top: 1px solid #eee;
} }
.event-tags, .event-references { .event-tags {
flex: 1; flex: 1;
} }
@ -130,16 +134,5 @@
.event-tags li, .event-references li { .event-tags li, .event-references li {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.event-id {
margin-top: 1.5rem;
color: #888;
text-align: right;
}
.nip05 {
color: #0066cc;
font-size: 0.9rem;
}
</style> </style>
{% endblock %} {% endblock %}

Loading…
Cancel
Save