{# Message bubble loop. Shared by _conversation.html (initial render) and _history_page.html (load-older paging). Expects `msgs` (list, oldest-first) and `is_group` (bool). #} {% for m in msgs %}
{% if is_group and not m.from_me and m.sender_name %}
{{ m.sender_name }}
{% endif %} {% if m.link_preview %} Link preview
{{ m.link_preview.domain }}
{{ m.link_preview.url }}
{% endif %} {% if m.attachments %} {# Split: ready images go to the gallery grid; everything else falls through #} {% set ready_imgs = m.attachments | selectattr('kind', 'equalto', 'image') | selectattr('ready') | list %} {% set other_atts = (m.attachments | rejectattr('kind', 'equalto', 'image') | list) + (m.attachments | selectattr('kind', 'equalto', 'image') | rejectattr('ready') | list) %} {# --- Gallery grid for ready images --- #} {% if ready_imgs %} {% set n = ready_imgs | length %} {# Choose grid class; cap display at 4 cells, show "+N" on the 4th when n>4 #} {% set grid_cls = 'gallery-' ~ (n if n <= 4 else '5p') %} {% set shown = ready_imgs[:4] %} {% set overflow = n - 4 if n > 4 else 0 %} {% endif %} {# --- Non-gallery attachments: pending images, video, audio, files --- #} {% if other_atts %}
{% for a in other_atts %} {% if not a.ready %}
syncing attachment…
{% elif a.kind == 'video' %} {% elif a.kind == 'audio' %} {% else %} {{ a.name }} {% endif %} {% endfor %}
{% endif %} {% endif %} {% if m.text and not m.link_preview %}
{{ m.text }}
{% endif %}
{{ m.ts }} {% if m.from_me and m.status and m.status != 'delivered' %} {% if m.status == 'failed' %} {{ m.label }} {% elif m.status == 'sent' %} sent {% else %} {{ m.label }} {% endif %} {% endif %}
{% endfor %}