Browse Source

Refactor comments, still

imwald
Nuša Pukšič 3 months ago
parent
commit
2bea95b769
  1. 41
      assets/controllers/comments_mercure_controller.js
  2. 108
      templates/components/Organisms/Comments.html.twig

41
assets/controllers/comments_mercure_controller.js

@ -1,14 +1,23 @@
import { Controller } from "@hotwired/stimulus"; import { Controller } from "@hotwired/stimulus";
import { getComponent } from "@symfony/ux-live-component";
export default class extends Controller { export default class extends Controller {
static values = { coordinate: String } static values = { coordinate: String }
static targets = ["list", "loading"] static targets = ["list", "loading"]
connect() { async connect() {
this._liveRoot = this.element.closest( // this.element IS the Live root now
'[data-controller~="live"]' this.component = await getComponent(this.element);
);
// Optional: hook for spinner polish
this.component.on('render:started', () => this._showLoading());
this.component.on('render:finished', () => this._hideLoading());
// Initial render from cache so UI isn’t empty
this._showLoading();
await this.component.render();
// Subscribe to Mercure and re-render on each ping
const hubUrl = window.MercureHubUrl || document.querySelector('meta[name="mercure-hub"]')?.content; const hubUrl = window.MercureHubUrl || document.querySelector('meta[name="mercure-hub"]')?.content;
if (!hubUrl) return; if (!hubUrl) return;
@ -16,21 +25,23 @@ export default class extends Controller {
url.searchParams.append('topic', `/comments/${this.coordinateValue}`); url.searchParams.append('topic', `/comments/${this.coordinateValue}`);
this.es = new EventSource(url.toString()); this.es = new EventSource(url.toString());
this.es.onmessage = (event) => this._pushToLive(event.data); this.es.onmessage = async (msg) => {
this._showLoading();
this.component.set('payloadJson', JSON.stringify(msg.data));
await this.component.render(); // Live re-hydrates from your server/cache
};
} }
disconnect() { disconnect() {
if (this.es) try { this.es.close(); } catch {} try { this.es?.close(); } catch {}
} }
_pushToLive(jsonString) { _showLoading() {
if (!this._liveRoot) return; if (this.hasLoadingTarget) this.loadingTarget.style.display = '';
// Find the hidden input bound to the LiveProp if (this.hasListTarget) this.listTarget.style.opacity = '0.6';
const input = this._liveRoot.querySelector('input[type="hidden"][data-model="payloadJson"]'); }
if (!input) return; _hideLoading() {
if (this.hasLoadingTarget) this.loadingTarget.style.display = 'none';
// Set value and dispatch an 'input' event so Live updates & re-renders if (this.hasListTarget) this.listTarget.style.opacity = '';
input.value = jsonString;
input.dispatchEvent(new Event('change', { bubbles: true }));
} }
} }

108
templates/components/Organisms/Comments.html.twig

@ -1,65 +1,61 @@
<div {% set existing = attributes.all()['data-controller'] ?? '' %}
{{ attributes }} {% set merged = (existing ? existing ~ ' ' : '') ~ 'comments-mercure' %}
data-comments-coordinate="{{ current }}">
<input type="hidden"
data-model="payloadJson"
value="{{ payloadJson|default('') }}" />
<div
class="comments"
data-controller="comments-mercure"
data-comments-mercure-coordinate-value="{{ current }}"
data-comments-mercure-target="root"
id="comments-{{ current|e('html_attr') }}">
{% if loading %} <div
<div class="comments-loading" data-comments-mercure-target="loading">Loading comments…</div> {{ attributes.add('data-controller', merged) }}
{% endif %} data-comments-mercure-coordinate-value="{{ current }}"
<div class="comments-list" data-comments-mercure-target="list" {% if loading %}style="display:none"{% endif %}> data-comments-mercure-target="loading"
{% for item in list %} data-comments-mercure-target="list"
<div class="card comment {% if item.kind is defined and item.kind == '9735' %}zap-comment{% endif %}"> id="comments-{{ current|e('html_attr') }}"
<div class="metadata"> class="comments"
{% if item.kind != '9735' %} >
<twig:Molecules:UserFromNpub ident="{{ item.pubkey }}" :user="authorsMetadata[item.pubkey]" />
{% elseif zappers[item.id] %}
<twig:Molecules:UserFromNpub ident="{{ zappers[item.id] }}" :user="authorsMetadata[zappers[item.id]]" />
{% else %}
<p><em>Unknown</em></p>
{% endif %}
<small>{{ item.created_at|date('F j Y') }}</small>
</div>
<div class="card-body"> {% if loading %}
{% if item.kind is defined and item.kind == '9735' %} <div class="comments-loading" data-comments-mercure-target="loading">Loading comments…</div>
<div class="zap-amount"> {% endif %}
{% if zapAmounts[item.id] is defined %} <div class="comments-list" data-comments-mercure-target="list" {% if loading %}style="display:none"{% endif %}>
<strong>{{ zapAmounts[item.id] }} sat</strong> {% for item in list %}
{% else %} <div class="card comment {% if item.kind is defined and item.kind == '9735' %}zap-comment{% endif %}">
<em>Zap</em> <div class="metadata">
{% endif %} {% if item.kind != '9735' %}
</div> <twig:Molecules:UserFromNpub ident="{{ item.pubkey }}" :user="authorsMetadata[item.pubkey]" />
{% endif %} {% elseif zappers[item.id] %}
<twig:Atoms:Content content="{{ item.content }}" /> <twig:Molecules:UserFromNpub ident="{{ zappers[item.id] }}" :user="authorsMetadata[zappers[item.id]]" />
</div> {% else %}
<p><em>Unknown</em></p>
{% endif %}
<small>{{ item.created_at|date('F j Y') }}</small>
</div>
{# Display Nostr link previews if links detected #} <div class="card-body">
{% if commentLinks[item.id] is defined and commentLinks[item.id]|length > 0 %} {% if item.kind is defined and item.kind == '9735' %}
<div class="card-footer nostr-previews mt-3"> <div class="zap-amount">
<div class="preview-container"> {% if zapAmounts[item.id] is defined %}
{% for link in commentLinks[item.id] %} <strong>{{ zapAmounts[item.id] }} sat</strong>
<div> {% else %}
<twig:Molecules:NostrPreview preview="{{ link }}" /> <em>Zap</em>
</div> {% endif %}
{% endfor %}
</div>
</div> </div>
{% endif %} {% endif %}
<twig:Atoms:Content content="{{ item.content }}" />
</div> </div>
{% else %}
<div class="no-comments">No comments yet.</div>
{% endfor %}
</div>
{# Display Nostr link previews if links detected #}
{% if commentLinks[item.id] is defined and commentLinks[item.id]|length > 0 %}
<div class="card-footer nostr-previews mt-3">
<div class="preview-container">
{% for link in commentLinks[item.id] %}
<div>
<twig:Molecules:NostrPreview preview="{{ link }}" />
</div>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% else %}
<div class="no-comments">No comments yet.</div>
{% endfor %}
</div> </div>
</div> </div>

Loading…
Cancel
Save