From 2bea95b76979ddfbf9d5390e60250557d294561f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nu=C5=A1a=20Puk=C5=A1i=C4=8D?= Date: Sun, 26 Oct 2025 19:32:01 +0100 Subject: [PATCH] Refactor comments, still --- .../comments_mercure_controller.js | 41 ++++--- .../components/Organisms/Comments.html.twig | 108 +++++++++--------- 2 files changed, 78 insertions(+), 71 deletions(-) diff --git a/assets/controllers/comments_mercure_controller.js b/assets/controllers/comments_mercure_controller.js index 231544d..1717b5e 100644 --- a/assets/controllers/comments_mercure_controller.js +++ b/assets/controllers/comments_mercure_controller.js @@ -1,14 +1,23 @@ import { Controller } from "@hotwired/stimulus"; +import { getComponent } from "@symfony/ux-live-component"; export default class extends Controller { static values = { coordinate: String } static targets = ["list", "loading"] - connect() { - this._liveRoot = this.element.closest( - '[data-controller~="live"]' - ); + async connect() { + // this.element IS the Live root now + 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; if (!hubUrl) return; @@ -16,21 +25,23 @@ export default class extends Controller { url.searchParams.append('topic', `/comments/${this.coordinateValue}`); 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() { - if (this.es) try { this.es.close(); } catch {} + try { this.es?.close(); } catch {} } - _pushToLive(jsonString) { - if (!this._liveRoot) return; - // Find the hidden input bound to the LiveProp - const input = this._liveRoot.querySelector('input[type="hidden"][data-model="payloadJson"]'); - if (!input) return; - - // Set value and dispatch an 'input' event so Live updates & re-renders - input.value = jsonString; - input.dispatchEvent(new Event('change', { bubbles: true })); + _showLoading() { + if (this.hasLoadingTarget) this.loadingTarget.style.display = ''; + if (this.hasListTarget) this.listTarget.style.opacity = '0.6'; + } + _hideLoading() { + if (this.hasLoadingTarget) this.loadingTarget.style.display = 'none'; + if (this.hasListTarget) this.listTarget.style.opacity = ''; } } diff --git a/templates/components/Organisms/Comments.html.twig b/templates/components/Organisms/Comments.html.twig index d236661..82997ea 100644 --- a/templates/components/Organisms/Comments.html.twig +++ b/templates/components/Organisms/Comments.html.twig @@ -1,65 +1,61 @@ -
- - - -
+{% set existing = attributes.all()['data-controller'] ?? '' %} +{% set merged = (existing ? existing ~ ' ' : '') ~ 'comments-mercure' %} - {% if loading %} -
Loading comments…
- {% endif %} -
- {% for item in list %} -
- +
-
- {% if item.kind is defined and item.kind == '9735' %} -
- {% if zapAmounts[item.id] is defined %} - {{ zapAmounts[item.id] }} sat - {% else %} - Zap - {% endif %} -
- {% endif %} - -
+ {% if loading %} +
Loading comments…
+ {% endif %} +
+ {% for item in list %} +
+ - {# Display Nostr link previews if links detected #} - {% if commentLinks[item.id] is defined and commentLinks[item.id]|length > 0 %} - + {# Display Nostr link previews if links detected #} + {% if commentLinks[item.id] is defined and commentLinks[item.id]|length > 0 %} + + {% endif %} +
+ {% else %} +
No comments yet.
+ {% endfor %}
+