{% macro avatar(src, cls="cg-avatar") -%} {%- endmacro %} {% macro date_label(d) -%} {{ d.strftime("%B ") }}{{ d.day }}, {{ d.year }} {%- endmacro %} {% macro time_label(ts) -%} {{ ts.strftime("%I:%M").lstrip("0") }} {{ ts.strftime("%p") }} {%- endmacro %} {% macro time_24(ts) -%} {{ ts.strftime("%H:%M") }} {%- endmacro %} {# Delivery ticks for messenger self-bubbles. `read_cls` colors the read state. #} {% macro ticks(status, read_cls="cg-tick-read") -%} {%- if status.value == "sending" %}πŸ•“ {%- elif status.value == "sent" %}βœ“ {%- elif status.value == "delivered" %}βœ“βœ“ {%- elif status.value == "read" %}βœ“βœ“ {%- endif -%} {%- endmacro %} {% macro reactions(msg, cls="cg-reactions") -%} {% if msg.reactions %}
{% for r in msg.reactions %}{{ r.emoji }}{% endfor %}
{% endif %} {%- endmacro %} {# Short preview of a replied-to message for a reply quote. #} {% macro reply_snippet(rep) -%} {%- set rt = rep.content.__class__.__name__ -%} {%- if rt == "Text" -%}{{ rep.content.body }} {%- else -%}{{ fallback_text(rep.content) }}{%- endif -%} {%- endmacro %} {# Quoted reply block shown at the top of a bubble. #} {% macro reply_quote(rep, prefix) -%} {{ rep.sender.name }} {{ reply_snippet(rep) }} {%- endmacro %} {# Animated three-dot "typing…" indicator. #} {% macro typing_dots() -%} {%- endmacro %} {# Inner UI of a voice message: play triangle, waveform, duration. No bubble. #} {% macro voice_inner(content) -%} {% for h in [7,11,16,9,14,20,8,13,18,10,22,12,17,9,15,7,19,11,14,8,16,10,13,7] %}{% endfor %} {{ '%d:%02d'|format(content.duration_seconds // 60, content.duration_seconds % 60) }} {%- endmacro %} {# Routes a message's content to the right element for a platform, honoring capability degradation. `prefix` is the platform css class prefix (e.g. "wa"). #} {% macro content_block(msg, caps, prefix) -%} {% set side = "self" if msg.is_self else "other" %} {% set t = msg.content.__class__.__name__ %} {%- if not caps.supports(msg.content) -%}
{{ fallback_text(msg.content) }}
{%- elif t == "Text" -%}
{% if msg.reply_to %}{{ reply_quote(msg.reply_to, prefix) }}{% endif %}{{ msg.content.body }}
{%- elif t == "Voice" -%}
{{ voice_inner(msg.content) }}
{%- elif t in ("Image", "GIF", "Sticker") -%} {% set src = media_src(msg) %} {% if src %}{% else %}
{% endif %} {% if msg.content.caption is defined and msg.content.caption %}
{{ msg.content.caption }}
{% endif %} {%- elif t == "System" -%}
{{ msg.content.text }}
{%- else -%}
{{ fallback_text(msg.content) }}
{%- endif -%} {%- endmacro %} {% macro fallback_text(content) -%} {% set t = content.__class__.__name__ %} {%- if t == "Voice" %}🎀 Voice message{% if content.duration_seconds %} Β· {{ content.duration_seconds }}s{% endif %} {%- elif t == "File" %}πŸ“Ž {{ content.name }}{% if content.size %} Β· {{ content.size }}{% endif %} {%- elif t == "Location" %}πŸ“ {{ content.label }} {%- elif t == "Image" %}πŸ–Ό Photo {%- elif t == "GIF" %}GIF {%- elif t == "Sticker" %}Sticker {%- elif t == "Text" %}{{ content.body }} {%- else %}{{ content }}{% endif %} {%- endmacro %}