Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement replies #402

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _data/activity_pub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ notifications:
created_at: 1726241977
dripline/storing-metadata-at-starling-lab.jsonld:
action: done
id: https://staging.hypha.coop/dripline/storing-metadata-at-starling-lab.jsonld
id: https://hypha.hypha.coop/dripline/storing-metadata-at-starling-lab.jsonld
created_at: 1728400393
actor_url: https://hypha.coop/about.jsonld
actor: "@[email protected]"
Expand Down
11 changes: 11 additions & 0 deletions _includes/activity_pub/actor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% comment %}
Render actor's name if it's available, otherwise just return the link.

@param actor [ActivityDrop] Actor
{% endcomment %}

{% if include.actor.available %}
<span class="break-wrap">{{ include.actor.name | strip_html }}</span>
{% else %}
<span class="break-wrap">{{ include.actor }}</span>
{% endif %}
28 changes: 28 additions & 0 deletions _includes/activity_pub/actor_mention.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% comment %}
@param actor [ActivityDrop] Actor
@param without_link [Boolean] Don't link
{% endcomment %}

{% if include.actor.available %}
{% assign id = include.actor.id | strip_html %}
{% assign instance_hostname = id | split: '/' %}
{% assign instance_hostname = instance_hostname[2] %}

{% capture mention %}
@<span>{{- include.actor.preferredUsername | strip_html -}}@{{- instance_hostname -}}</span>
{% endcapture %}

{% capture mention %}
<span class="h-card break-wrap" translate="no">
{% if include.without_link %}
<span class="mention">{{- mention -}}</span>
{% else %}
{% include external_link.html class="u-url mention" href=id text=mention %}
{% endif %}
</span>
{% endcapture %}

{{ mention | normalize_whitespace }}
{% else %}
{{ include.actor }}
{% endif %}
22 changes: 22 additions & 0 deletions _includes/activity_pub/button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{%- comment -%}
Un botón con link, por ejemplo para Support Us. Si el link es externo,
agregar el parámetro de seguridad noopener.

@param :fa [String]
@param :header [Capture] el contenido del encabezado
@param :body [Capture] el contenido del cuerpo principal
@param :footer [Capture] el contenido del footer
@param :header_class [String] las clases que lleva el encabezado
@param :body_class [String] las clases que lleva el cuerpo principal
@param :footer_class [String] las clases que lleva el footer
@param :content_class [String] las clases que lleva todo el bloque de contenido
@param :button_class [String] las clases que lleva cada botón
{%- endcomment -%}

<div class="d-inline {{include.button_class}}" data-controller="modal">
<button class="btn btn-sm" data-action="click->modal#show">
{%- include fa.html icon=include.fa class="lead" description=include.description -%}
</button>

{% include activity_pub/generic_modal.html header=include.header body=include.body footer=include.footer header_class=include.header_class body_class=include.body_class footer_class=include.footer_class content_class=include.content_class %}
</div>
16 changes: 16 additions & 0 deletions _includes/activity_pub/button_bar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{%- comment -%}
Botonera para botones de íconos.

@param :uri [String] La URL sobre la que se interactua
@param :profile [ActivityDrop] Actor
{%- endcomment -%}

{% assign uri = include.uri | default: include.url | default: 'YOU FORGOT THIS PARAM' | strip_html %}
{% assign actions = site.data.actions.actions %}

<div class="d-flex">
{% for action in actions %}
{% assign fa = action.icon %}
{% include activity_pub/login_modal.html action=action fa=fa uri=uri profile=include.profile description=action.title %}
{% endfor %}
</div>
28 changes: 28 additions & 0 deletions _includes/activity_pub/cards.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{%- comment -%}
Nested cards

@param :profile [ActivityDrop] Actor
@param :activity [ActivityDrop] Note
@param :replies [ActivityDrop] Collection
{%- endcomment -%}

{%
include activity_pub/toot_card.html
profile=include.profile
activity=include.activity
component_class="my-3"
%}

{% if include.replies.available %}
{% assign replies = include.replies.all_items | sort: 'published' %}
{% for reply in replies %}
<blockquote class="border-left border-gray-light border-width-3 pl-3">
{%
include activity_pub/cards.html
profile=reply.attributedTo
activity=reply
replies=reply.replies
%}
</blockquote>
{% endfor %}
{% endif %}
2 changes: 2 additions & 0 deletions _includes/activity_pub/fediverse_interactions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{% assign extra = 'data-action="tabs#toggle" data-tabs-target="value"' %}
{% include bootstrap/custom_select.html extra=extra options=site.i18n.fediverse_interactions %}
55 changes: 55 additions & 0 deletions _includes/activity_pub/generic_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{%- comment -%}
Modal preparado para recibir contenido + header y footer

@param :header [Capture] contenido del header
@param :body [Capture] contenido del modal
@param :footer [Capture] contenido del footer
@param :header_class [String] clases del header
@param :body_class [String] clases del cuerpo principal
@param :footer_class [String] clases del header
@param :content_class [String] clases todo el bloque
{%- endcomment -%}

{% assign header = include.header %}
{% assign header_class = include.header_class %}
{% assign body = include.body %}
{% assign body_class = include.body_class %}
{% assign footer = include.footer %}
{% assign footer_class = include.footer_class %}
{% assign content_class = include.content_class %}

<div
class="modal fade mw-100vw"
tabindex="-1"
aria-hidden="true"
data-modal-target="modal"
data-action="keydown->modal#hideWithEscape"
>
<div class="modal-backdrop fade zindex-backdrop" data-modal-target="backdrop" data-action="click->modal#hide"></div>
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg zindex-modal" role="document">
<div class="modal-content {{content_class}}">
{% if header %}
<div class="modal-header {{header_class}}">
{{ header }}
</div>
{% else %}
<div class="modal-header justify-content-end border-bottom-0 p-0 {{header_class}}">
<span class="px-3 py-2 m-0 h1 font-weight-bold" type="button" data-action="click->modal#hide">&times</span>
<span class="sr-only">{{ site.i18n.close }}</span>
</div>
{% endif %}

<div class="modal-body {{body_class}}">
{{ body }}
</div>

<div class="modal-footer flex-nowrap {{footer_class}}">
{% if footer %}
{{ footer }}
{% else %}
<button class="btn btn-secondary m-0" type="button" data-action="modal#hide">{{ site.i18n.close }}</button>
{% endif %}
</div>
</div>
</div>
</div>
27 changes: 27 additions & 0 deletions _includes/activity_pub/image_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{%- comment -%}
Modal con imagen

@param :image [Image] la imagen que queremos en el modal, contiene url y alt text
{%- endcomment -%}

{% assign extra = 'data-action="click->modal#show"' %}
{% assign alt = include.image.name | strip_html | escape %}
{% assign src = include.image.url | strip_html | uri_escape %}

{% capture body %}
<img class="background-white mw-100" title="{{ alt }}" alt="{{ alt }}" src="{{ src }}">
{% endcapture %}

<div class="{{ include.extra }} px-1" data-controller="modal">
{%
include embed_responsive.html
x=16
y=9
src=src
alt=alt
extra=extra
width=300
img_class="cursor-pointer min-w-100px w-100 object-fit-cover"
%}
{% include activity_pub/generic_modal.html header_class="text-white" body=body body_class="d-flex justify-content-center" footer_class="d-none" content_class="background-transparent border-0" %}
</div>
78 changes: 78 additions & 0 deletions _includes/activity_pub/interactions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{% comment %}
@param activity [ActivityDrop]
{% endcomment %}

{% assign items = site.i18n.fediverse_interactions %}
{% assign reactions = '' | split: ',' %}
{% assign activities = reactions %}

{% if page.activity.replies.available %}
{% assign activities = page.activity.replies.all_items | sort: 'published' %}
{% endif %}

{% if include.activity.likes.available %}
{% assign reactions = reactions | concat: include.activity.likes.all_items %}
{% endif %}

{% if include.activity.shares.available %}
{% assign reactions = reactions | concat: include.activity.shares.all_items %}
{% endif %}

{% assign reactions = reactions | sort: 'published' %}

{% assign all_interactions = activities | concat: reactions | sort: 'published' %}

<div class="w-100" data-controller="tabs" data-tabs-hide-class="hide" data-tabs-show-class="show">
{% include activity_pub/button_bar.html uri=include.activity.id profile=include.profile %}

<hr>

<h3 class="text-uppercase">{{ site.i18n.ver_interacciones }}</h3>

<div class="d-flex flex-row align-items-center mt-2 mb-5">
{% include activity_pub/fediverse_interactions.html %}

{% assign text = site.i18n.help | markdownify | replace: '<a ', "<a target='_blank' rel='noopener' " %}
{% include activity_pub/text_modal.html text=text fa="question-circle-o" %}
</div>

<div class="w-100 d-none fade hide" data-tabs-target="tab" id="conversation">
{% unless activities == empty %}
{% for activity in activities %}
{% include activity_pub/cards.html activity=activity profile=activity.attributedTo replies=activity.replies %}
{% endfor %}
{% else %}
<p class="h1">
{{ site.i18n.no_interactions_yet.conversation }}
<p>
{% endunless %}
</div>

<div class="w-100 d-none fade hide" data-tabs-target="tab" id="reactions">
{% unless reactions == empty %}
{% include activity_pub/reactions.html reactions=reactions %}
{% else %}
<p class="h1">
{{ site.i18n.no_interactions_yet.reactions }}
<p>
{% endunless %}
</div>

<div class="w-100 fade show" data-tabs-target="tab" id="both">
{% unless all_interactions == empty %}
{% for interaction in all_interactions %}
{% assign minus = forloop.index0 | minus: 1 %}
{% assign previous = all_interactions[minus] %}
{% if interaction.type == 'Announce' or interaction.type == 'Like' %}
{% include activity_pub/reaction.html activity=interaction previous=previous %}
{% else %}
{% include activity_pub/cards.html activity=interaction profile=interaction.attributedTo replies=interaction.replies %}
{% endif %}
{% endfor %}
{% else %}
<p class="h1">
{{ site.i18n.no_interactions_yet.both }}
<p>
{% endunless %}
</div>
</div>
69 changes: 69 additions & 0 deletions _includes/activity_pub/login_modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{%- comment -%}
Modal para loguearse al fediverso

@param :action [String] acción que le usuarie quiere realizar desde el fediverso
@param :fa [String] nombre del ícono que usa fork-awesome
@param :uri [String] la URL sobre la que se interactúa
@param :profile [ActivityDrop] Actor
{%- endcomment -%}

{% assign action = include.action %}
{% assign fa = include.fa %}
{% capture name %}
{% include activity_pub/actor.html actor=include.profile %}
{% endcapture %}

{% capture header %}

<div class="d-flex align-items-center h1 justify-content-center w-100">
<span class="d-flex responsive-header font-weight-bold text-center">
<i class="fa fa-{{fa}} text-primary mr-2"></i>
<span class="break-wrap">{{ site.i18n.login_modal[action.title].text | replace: "$usuarie", name }}</span>
<div>
<span class="px-3 py-2 m-0 h1" type="button" data-action="click->modal#hide">&times</span>
<span class="sr-only">{{ site.i18n.close }}</span>
</div>
</span>
</div>
{% endcapture %}

{% capture body %}
<p class="mb-2">{{site.i18n.login_modal.top_text | markdownify | replace: "$action", site.i18n.login_modal[action.title].title }}</p>
<div class="mt-3 mb-2 h5">{{site.i18n.login_modal.question | markdownify}}</div>
<div class="mb-3">
<form
class="needs-validation"
data-controller="authorize-interaction"
data-action="authorize-interaction#submit:prevent"
data-authorize-interaction-uri-value="{{ include.uri | strip_html | absolute_url | uri_escape }}"
>
<div class="form-row align-items-center border-lg border-lg-primary py-1">
<div class="col-12 col-lg mb-1 mb-lg-0">
<label class="sr-only">{{site.i18n.login_modal.placeholder}}</label>
<input
class="form-control border border-primary border-lg-0"
placeholder="{{site.i18n.login_modal.placeholder}}"
autocomplete="impp"
required
data-authorize-interaction-target="instance"
data-action="authorize-interaction#revalid"
type="search">
<div class="invalid-feedback">
{{- site.i18n.login_modal.authorize_interaction_unsupported -}}
</div>
</div>

<div class="col-12 col-lg-auto">
<button class="btn btn-primary btn-block py-btn-padding-y lh-btn-line-height f-16 font-weight-bold" type="submit">{{ site.i18n.take_me_home }}</button>
</div>
</div>
</form>
</div>
<small class="d-block mb-2">{{site.i18n.login_modal.small_text}}</small>
<span>{{site.i18n.login_modal.bottom_text | markdownify}}</span>
{% endcapture %}

{% capture footer %}
{% endcapture %}

{% include activity_pub/button.html header=header body=body footer=footer header_class="justify-content-center border-bottom-0" body_class="justify-content-center" footer_class="border-top-0" content_class="p-2" button_class="mx-1" fa=action.icon description=include.description %}
Loading