Browse Source

implement recursive mentions folding tree

main
ghost 1 year ago
parent
commit
0aca404bc0
  1. 20
      public/css/default.css
  2. 75
      src/Controller/RoomController.php
  3. 48
      templates/default/room/index.html.twig

20
public/css/default.css

@ -95,36 +95,32 @@ main ul
main ul ul main ul ul
{ {
margin-bottom: 16px; margin-left: 24px;
margin-left: 16px;
margin-top: 16px;
} }
main ul > li main ul li
{ {
margin: 8px 0; border-top: 1px var(--color-default) solid;
padding: 8px 0;
word-wrap: break-word; word-wrap: break-word;
border-bottom: 1px var(--color-default) solid;
} }
main ul > li:last-child main ul li div
{ {
border-bottom: none; padding: 16px 0;
} }
main ul > li > p main ul li p
{ {
padding: 8px 0; padding: 8px 0;
} }
main ul > li > p > br /* tmp solution for current twig filters implementation */ main ul li p > br /* tmp solution for current twig filters implementation */
{ {
display: block; display: block;
margin: 4px 0; margin: 4px 0;
} }
main ul li > span > svg main ul li span > svg
{ {
cursor: default; cursor: default;
fill: var(--color-default); fill: var(--color-default);

75
src/Controller/RoomController.php

@ -103,14 +103,23 @@ class RoomController extends AbstractController
// Require valid kevachat meta // Require valid kevachat meta
if ($data = $this->_post($pending)) if ($data = $this->_post($pending))
{ {
$feed[] = // Detect parent post
preg_match('/^@([A-z0-9]{64})\s/i', $data->message, $mention);
$feed[$data->id] =
[ [
'id' => $data->id, 'id' => $data->id,
'user' => $data->user, 'user' => $data->user,
'icon' => $data->icon, 'icon' => $data->icon,
'message' => $data->message, 'time' => $data->time,
'timestamp' => $data->time, 'parent' => isset($mention[1]) ? $mention[1] : null,
'time' => date('c', $data->time), 'message' => trim(
preg_replace( // remove mention from folded message
'/^@([A-z0-9]{64})\s/i',
'',
$data->message
)
),
'pending' => true 'pending' => true
]; ];
} }
@ -128,14 +137,23 @@ class RoomController extends AbstractController
// Require valid kevachat meta // Require valid kevachat meta
if ($data = $this->_post($post)) if ($data = $this->_post($post))
{ {
$feed[] = // Detect parent post
preg_match('/^@([A-z0-9]{64})\s/i', $data->message, $mention);
$feed[$data->id] =
[ [
'id' => $data->id, 'id' => $data->id,
'user' => $data->user, 'user' => $data->user,
'icon' => $data->icon, 'icon' => $data->icon,
'message' => $data->message, 'time' => $data->time,
'timestamp' => $data->time, 'parent' => isset($mention[1]) ? $mention[1] : null,
'time' => date('c', $data->time), 'message' => trim(
preg_replace( // remove mention from folded message
'/^@([A-z0-9]{64})\s/i',
'',
$data->message
)
),
'pending' => false 'pending' => false
]; ];
} }
@ -151,6 +169,14 @@ class RoomController extends AbstractController
$feed $feed
); );
// Init folding &data pool
$fold = $feed;
// Build threading tree
$tree = $this->_tree(
$fold
);
// RSS // RSS
if ('rss' === $request->get('feed')) if ('rss' === $request->get('feed'))
{ {
@ -176,6 +202,7 @@ class RoomController extends AbstractController
'default/room/index.html.twig', 'default/room/index.html.twig',
[ [
'feed' => $feed, 'feed' => $feed,
'tree' => $tree,
'request' => $request 'request' => $request
] ]
); );
@ -440,4 +467,36 @@ class RoomController extends AbstractController
return $identicon->getImageDataUri('webp'); return $identicon->getImageDataUri('webp');
} }
private function _tree(
array &$feed,
?string $parent = null
): array
{
$tree = [];
foreach ($feed as $post)
{
if ($post['parent'] == $parent)
{
$children = $this->_tree(
$feed,
$post['id']
);
if ($children)
{
$post['tree'] = $children;
}
$tree[$post['id']] = $post;
unset(
$feed[$post['id']]
);
}
}
return $tree;
}
} }

48
templates/default/room/index.html.twig

@ -1,20 +1,10 @@
{% extends 'default/layout.html.twig' %} {% macro recursive_post_tree(namespace, tree) %}
{% block head_title_content %}{{ request.get('namespace') | keva_namespace_value }} - {{ 'KevaChat' | trans }}{% endblock %} {% import _self as self %}
{% block main_content %} {% if tree | length %}
{{
render(
controller(
'App\\Controller\\ModuleController::room',
{
request: request
}
)
)
}}
{% if feed %}
<ul> <ul>
{% for post in feed %} {% for post in tree %}
<li> <li>
<div>
<a name="{{ post.id }}"></a> <a name="{{ post.id }}"></a>
{% if post.icon %} {% if post.icon %}
<img src="{{ post.icon }}" alt="icon" /> <img src="{{ post.icon }}" alt="icon" />
@ -24,9 +14,9 @@
</strong> </strong>
{% endif %} {% endif %}
&bull; &bull;
<a rel="nofollow" href="{{ path('room_namespace', { namespace : request.get('namespace') }) }}#{{ post.id }}" title="{{ post.time }}">{{ post.timestamp | format_ago }}</a> <a rel="nofollow" href="{{ path('room_namespace', { namespace : namespace }) }}#{{ post.id }}" title="{{ post.time | date('c') }}">{{ post.time | format_ago }}</a>
&bull; &bull;
<a rel="nofollow" href="{{ path('room_namespace', { namespace : request.get('namespace'), txid : post.id }) }}#{{ post.id }}">{{ 'reply' | trans }}</a> <a rel="nofollow" href="{{ path('room_namespace', { namespace : namespace, txid : post.id }) }}#{{ post.id }}">{{ 'reply' | trans }}</a>
{% if post.pending %} {% if post.pending %}
<span title="{{ 'pending in pool' | trans }}"> <span title="{{ 'pending in pool' | trans }}">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16">
@ -44,13 +34,37 @@
| nl2br | nl2br
| markdown_to_html | markdown_to_html
}} }}
</div>
{% if post.tree | length %}
{{ self.recursive_post_tree(namespace, post.tree) }}
{% endif %}
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %}
{% endmacro %}
{% from _self import recursive_post_tree %}
{% extends 'default/layout.html.twig' %}
{% block head_title_content %}{{ request.get('namespace') | keva_namespace_value }} - {{ 'KevaChat' | trans }}{% endblock %}
{% block main_content %}
{{
render(
controller(
'App\\Controller\\ModuleController::room',
{
request: request
}
)
)
}}
{% if tree %}
{{ recursive_post_tree(request.get('namespace'), tree) }}
{% else %} {% else %}
<ul> <ul>
<li> <li>
<div>
{{ 'room does not contain kevachat messages' | trans }} {{ 'room does not contain kevachat messages' | trans }}
</div>
</li> </li>
</ul> </ul>
{% endif %} {% endif %}

Loading…
Cancel
Save