{% macro display_actor_inline(follower, size=50) -%} {% if follower and follower.id %} <a class="actor-box" href="{{follower | url_or_id | get_url }}" style="clear:both;"> <span style="float:left;padding-right:15px;"> {% if not follower.icon %} <img class="actor-icon" src="/static/nopic.png" style="width:{{ size }}px"> {% else %} <img class="actor-icon" src="{{ follower.icon.url | get_actor_icon_url(size) }}" style="width:{{ size }}px;">{% endif %} </span> <div class="actor-inline"> <div style="font-weight:bold">{{ follower.name or follower.preferredUsername }}</div> <small class="lcolor">@{{ follower.preferredUsername }}@{{ follower | url_or_id | get_url | domain }}</small> </div> </a> {% endif %} {%- endmacro %} {% macro display_note(obj, perma=False, ui=False, likes=[], shares=[], meta={}, no_color=False) -%} {% if meta.object_actor %} {% set actor = meta.object_actor %} {% elif meta.actor %} {% set actor = meta.actor %} {% else %} {% set actor = obj.attributedTo | get_actor %} {% endif %} {% if session.logged_in %} {% set perma_id = obj.id | permalink_id %} {% if request.args.get('older_than') %} {% set redir = request.path + "?older_than=" + request.args.get('older_than') + "#activity-" + perma_id %} {% elif request.args.get('newer_than') %} {% set redir = request.path + "?newer_than=" + request.args.get('newer_than') + "#activity-" + perma_id %} {% else %} {% set redir = request.path + "#activity-" + perma_id %} {% endif %} {% set aid = obj.id | quote_plus %} {% endif %} {% set real_end_time = obj.closed or obj.endTime %} <div class="note-box"> <div class="note h-entry" id="activity-{{ obj.id | permalink_id }}"> <div class="h-card p-author"> <a class="u-url u-uid no-hover" href="{{ actor | url_or_id | get_url }}"><img class="u-photo" src="{% if not actor.icon %}/static/nopic.png{% else %}{{ actor.icon.url | get_actor_icon_url(50) }}{% endif %}"> </a> <data class="p-name" value="{{ actor.name or actor.preferredUsername }}"></data> </div> <div class="note-wrapper"> <div style="clear:both;height:20px;"> <a href="{{ actor | url_or_id | get_url }}" style="margin:0;text-decoration:none;margin: 0;text-decoration: none;display: block;width: 75%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;float: left;" class="no-hover"><strong>{{ actor.name or actor.preferredUsername }}</strong> <span class="l">@{% if not no_color and obj.id | is_from_outbox %}<span class="pcolor">{{ actor.preferredUsername }}</span>{% else %}{{ actor.preferredUsername }}{% endif %}@{% if not no_color and obj.id | is_from_outbox %}<span class="pcolor">{{ actor | url_or_id | get_url | domain }}</span>{% else %}{{ actor | url_or_id | get_url | domain }}{% endif %}</span></a> {% if not perma %} <span style="float:right;width: 25%;text-align: right;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;display: block;"> <a rel="noopener" class="u-url u-uid note-permalink l" href="{{ obj | url_or_id | get_url }}"> <time class="dt-published" title="{{ obj.published }}" datetime="{{ obj.published }}">{{ obj.published | format_timeago }}</time></a> </span> {% endif %} </div> {% if obj.summary %}<p class="p-summary">{{ obj.summary | clean | safe }}</p>{% endif %} {% if obj | has_type('Video') %} <div class="note-video"> <video controls preload="metadata" src="{{ obj.url | get_video_url }}" width="480"> </video> </div> {% endif %} <div class="note-container{% if perma %} perma{%endif%} p-name e-content"> {% if obj | has_type(['Article', 'Page']) %} {{ obj.name }} <a href="{{ obj | url_or_id | get_url }}">{{ obj | url_or_id | get_url }}</a> {% elif obj | has_type('Question') %} {{ obj.content | clean | safe }} <ul style="list-style:none;padding:0;"> {% set total_votes = obj | get_total_answers_count(meta) %} {% for oneOf in obj.oneOf %} {% set pct = 0 %} {% if total_votes > 0 %} {% set cnt = oneOf.name | get_answer_count(obj, meta) %} {% set pct = cnt * 100.0 / total_votes %} {% endif %} <li class="answer"> {% if session.logged_in and not meta.poll_answers_sent and not (real_end_time | gtnow) and not (obj.id | is_from_outbox) %} <span><form action="/api/vote" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="choice" value="{{ oneOf.name }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">vote</button> </form></span>{% endif %} <span class="answer-bar color-menu-background" style="width:{{pct}}%;"></span> <span class="answer-text"> <span>{{ '%0.0f'| format(pct) }}%</span> {{ oneOf.name }} {% if oneOf.name | poll_answer_key in meta.poll_answers_sent %}(your vote){% endif %} </span> </li> {% endfor %} {% if obj.anyOf %} {% for anyOf in obj.anyOf %} {% set pct = 0 %} {% if total_votes > 0 %} {% set cnt = anyOf.name | get_answer_count(obj, meta) %} {% set pct = cnt * 100.0 / total_votes %} {% endif %} <li class="answer"> {% set already_voted = anyOf.name | poll_answer_key in meta.poll_answers_sent %} {% if session.logged_in and not already_voted and not (real_end_time | gtnow) and not (obj.id | is_from_outbox) %} <span><form action="/api/vote" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="choice" value="{{ anyOf.name }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">vote</button> </form></span> {% elif session.logged_in and already_voted and not (real_end_time | gtnow) %} <span style="position:relative;top:5px;height:10px;width:50px;display:inline-block;"></span> {% endif %} <span class="answer-bar color-menu-background" style="width:{{pct}}%;"></span> <span class="answer-text"> <span>{{ '%0.0f'| format(pct) }}%</span> {{ anyOf.name }} {% if anyOf.name | poll_answer_key in meta.poll_answers_sent %}(your vote){% endif %} </span> </li> {% endfor %} {% endif %} </ul> <p><small> {% if real_end_time | gtnow %} Ended {{ real_end_time | format_timeago }} with <strong>{{ total_votes }}</strong> vote{% if total_votes | gtone %}s{% endif %}. {% else %} Ends {{ real_end_time | format_timeago }} (<strong>{{ total_votes }}</strong> vote{% if total_votes | gtone %}s{% endif %} as of now). {% endif %} </small></p> {% else %} {{ obj.content | clean | safe }} {% endif %} </div> {% if obj.attachment and obj | has_type('Note') %} <div style="padding:20px 0;"> {% if obj.sensitive and not request.args.get("show_sensitive") == perma_id %} <div style="clear:both"> <form action="{{redir}}" class="action-form" method="GET" style="display:inline-block"> <input type="hidden" name="show_sensitive" value="{{perma_id}}"> {% if request.path == url_for("admin.admin_lookup") %} <input type="hidden" name="url" value="{{obj.id}}"> {% endif %} <button type="submit" class="bar-item-reverse">display sensitive content</button> </form> </div> {% else %} {% if obj.sensitive %} <div style="clear:both;margin-bottom: 20px;"> <form action="{{redir}}" class="action-form" method="GET" style="display:inline-block"> {% if request.path == url_for("admin.admin_lookup") %} <input type="hidden" name="url" value="{{obj.id}}"> {% endif %} <button type="submit" class="bar-item">hide sensitive content</button> </form> </div> {% endif %} {% if obj.attachment | not_only_imgs %} <h3 class="l">Attachments</h3> <ul style="padding:0;"> {% endif %} {% for a in obj.attachment %} {% if (a.mediaType and a.mediaType.startswith("image/")) or (a.type and a.type == 'Image') %} <a href="{{ a.url | get_attachment_url(None) }}"><img src="{{a.url | get_attachment_url(720) }}" class="img-attachment"></a> {% elif (a.mediaType and a.mediaType.startswith("video/")) %} <li><video controls preload="metadata" src="{{ a.url | get_attachment_url(None) }}" width="480"></video></li> {% else %} <li><a href="{{a.url }}" class="l">{% if a.filename %}{{ a.filename }}{% else %}{{ a.url }}{% endif %}</a></li> {% endif %} {% endfor %} {% if obj.attachment | not_only_imgs %} </ul> {% endif %} {% endif %} </div> {% endif %} {% if meta and meta.og_metadata and obj | has_type('Note') %} {% for og in meta.og_metadata %} {% if og.url %} <a href="{{ og.url }}" class="og-link" style="margin:30px 0;clear:both;display: flex;"> <div> <img style="width:100px;border-radius:3px;" src="{{ og.image | get_og_image_url }}"> </div> <div style="padding:0 20px;"> <strong>{{ og.title }}</strong> <p>{{ og.description | truncate(80) }}</p> <small>{{ og.site_name }}</small> </div> </a> {% endif %} {% endfor %} {% endif %} <div class="bottom-bar"> {% if perma %} <span class="perma-item" style="float:left;padding:5px;">{{ obj.published | format_time }}</span> {% endif %} {% if meta.count_reply and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_reply }}</strong> replies</a> {% elif meta.count_reply and session.logged_in %} <a class="bar-item" href="/admin/thread?oid={{aid}}"><strong>{{ meta.count_reply }}</strong> replies</a>{% endif %} {% if not perma and meta.count_boost and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_boost }}</strong> boosts</a>{% endif %} {% if not perma and meta.count_like and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_like }}</strong> likes</a>{% endif %} {% if session.logged_in %} {% if ui%} <a class="bar-item" href="/admin/new?reply={{ aid }}">reply</a> {% if meta.object_visibility | visibility_is_public %} {% if meta.boosted %} <form action="/api/undo" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ meta.boosted }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">unboost</button> </form> {% else %} <form action="/api/boost" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">boost</button> </form> {% endif %} {% endif %} {% if meta.liked %} <form action="/api/undo" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ meta.liked }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">unlike</button> </form> {% else %} <form action="/api/like" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">like</button> </form> {% endif %} {% if meta.bookmarked or request.path == url_for("admin.admin_bookmarks") %} <form action="/api/bookmark" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="undo" value="yes"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">unbookmark</button> </form> {% else %} <form action="/api/bookmark" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">bookmark</button> </form> {% endif %} {% endif %} {% if obj.id | is_from_outbox %} <form action="/api/note/delete" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item" onclick="return confirm('Confirm the delete action?');">delete</button> </form> {% if meta.pinned %} <form action="/api/note/unpin" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">unpin</button> </form> {% else %} <form action="/api/note/pin" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item">pin</button> </form> {% endif %} {% else %} <form action="/api/block" class="action-form" method="POST"> <input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="actor" value="{{ actor.id }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <button type="submit" class="bar-item" onclick="return confirm('Confirm the block action?');">block</button> </form> {% endif %} {% endif %} <a class="bar-item" href="{{ obj | url_or_id | get_url }}">permalink</a> {% if session.logged_in %} <a class="bar-item bar-item-no-border">{{ meta.object_visibility | visibility }}</a> {% endif %} </div> {% if likes or shares %} <div style="padding-top:20px;" class="pure-g"> {% if likes %} <div class="pure-u-1-2"> <h4 style="font-weight:normal"><strong>{{ likes|length }}</strong> likes</h4>{% for like in likes %} {{ display_actor_inline(like) }} {% endfor %} </div> {% endif %} {% if shares %} <div class="pure-u-1-2"> <h4 style="font-weight:normal"><strong>{{ shares|length }}</strong> boosts</h4>{% for boost in shares %} {{ display_actor_inline(boost) }} {% endfor %} </div> {% endif %} </div> {% endif %} </div> </div> </div> {%- endmacro %} {% macro display_thread(thread, likes=[], shares=[]) -%} {% for reply in thread %} {% if reply._requested %} {{ display_note(reply.activity.object, perma=True, ui=False, likes=likes, shares=shares, meta=reply.meta) }} {% else %} {{ display_note(reply.activity.object, perma=False, ui=True, meta=reply.meta) }} {% endif %} {% endfor %} {% endmacro -%} {% macro display_pagination(older_than, newer_than) -%} <div class="clear"> {% if older_than %} <a href="{{ config.BASE_URL }}{{ request.path }}?older_than={{older_than}}{% if request.args.get('limit') %}&limit={{request.args.get('limit')}}{% endif %}" rel="next" class="older-link lcolor"><span class="pcolor">🡨</span> Older</a> {% endif %} {% if newer_than %} <a href="{{ config.BASE_URL }}{{ request.path }}?newer_than={{newer_than}}{% if request.args.get('limit') %}&limit={{request.args.get('limit')}}{% endif %}" rel="prev" class="newer-link lcolor">Newer <span class="pcolor">🡪</span></a> {% endif %} </div> {% endmacro -%} {% macro display_pagination_links(older_than, newer_than) -%} {% if older_than %}<link rel="next" href="{{ config.BASE_URL }}{{ request.path }}?older_than={{older_than}}">{% endif %} {% if newer_than %}<link rel="prev" href="{{ config.BASE_URL }}{{ request.path }}?newer_than={{newer_than}}">{% endif %} {% endmacro -%}