diff --git a/app/admin.py b/app/admin.py index ece448e..c45575f 100644 --- a/app/admin.py +++ b/app/admin.py @@ -393,6 +393,9 @@ async def admin_direct_messages( db_session: AsyncSession = Depends(get_db_session), cursor: str | None = None, ) -> templates.TemplateResponse: + # The process for building DMs thread is a bit compex in term of query + # but it does not require an extra tables to index/manage threads + inbox_convos = ( ( await db_session.execute( @@ -407,6 +410,8 @@ async def admin_direct_messages( .where( models.InboxObject.visibility == ap.VisibilityEnum.DIRECT, models.InboxObject.ap_context.is_not(None), + # Skip transient object like poll relies + models.InboxObject.is_transient.is_(False), ) .group_by(models.InboxObject.ap_context, models.InboxObject.actor_id) ) @@ -427,6 +432,8 @@ async def admin_direct_messages( .where( models.OutboxObject.visibility == ap.VisibilityEnum.DIRECT, models.OutboxObject.ap_context.is_not(None), + # Skip transient object like poll relies + models.OutboxObject.is_transient.is_(False), ) .group_by(models.OutboxObject.ap_context) ) @@ -435,6 +442,7 @@ async def admin_direct_messages( .all() ) + # Build a "threads index" by combining objects from the inbox and outbox convos = {} for inbox_convo in inbox_convos: if inbox_convo.ap_context not in convos: @@ -467,6 +475,7 @@ async def admin_direct_messages( convos[outbox_convo.ap_context]["most_recent_from_outbox"], ) + # Fetch the latest object for each threads convos_with_last_from_inbox = [] convos_with_last_from_outbox = [] for context, convo in convos.items(): @@ -514,6 +523,8 @@ async def admin_direct_messages( .unique() .all() ) + + # Build the template response threads = [] for anybox_object in sorted( last_from_inbox + last_from_outbox, diff --git a/app/boxes.py b/app/boxes.py index 8f1f0a8..fcbda71 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -154,6 +154,12 @@ async def send_announce(db_session: AsyncSession, ap_object_id: str) -> None: if not inbox_object: raise ValueError(f"{ap_object_id} not found in the inbox") + if inbox_object.visibility not in [ + ap.VisibilityEnum.PUBLIC, + ap.VisibilityEnum.UNLISTED, + ]: + raise ValueError("Cannot announce non-public object") + announce_id = allocate_outbox_id() announce = { "@context": ap.AS_CTX, diff --git a/app/main.py b/app/main.py index 37a3adc..217e611 100644 --- a/app/main.py +++ b/app/main.py @@ -76,7 +76,6 @@ _RESIZED_CACHE: MutableMapping[tuple[str, int], tuple[bytes, str, Any]] = LFUCac # TODO(ts): # # Next: -# - Add a TTL cache for the LD sig (no need to re-compute) # - only show 10 most recent threads in DMs # - custom CSS for disabled button (e.g. sharing on a direct post) # - prevent double accept/double follow diff --git a/app/templates/utils.html b/app/templates/utils.html index 7860f50..300c701 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -105,12 +105,12 @@ {% endmacro %} -{% macro admin_announce_button(ap_object_id, disabled=False, permalink_id=None) %} +{% macro admin_announce_button(ap_object_id, permalink_id=None) %}
{{ embed_csrf_token() }} {{ embed_redirect_url(permalink_id) }} - +
{% endmacro %} @@ -574,13 +574,15 @@ {% endif %} + {% if object.visibility in [visibility_enum.PUBLIC, visibility_enum.UNLISTED] %}
  • {% if object.announced_via_outbox_object_ap_id %} {{ admin_undo_button(object.liked_via_outbox_object_ap_id, "unshare") }} {% else %} - {{ admin_announce_button(object.ap_id, disabled=object.visibility not in [visibility_enum.PUBLIC, visibility_enum.UNLISTED], permalink_id=object.permalink_id) }} + {{ admin_announce_button(object.ap_id, permalink_id=object.permalink_id) }} {% endif %}
  • + {% endif %}
  • {{ admin_profile_button(object.actor.ap_id) }}