mirror of
https://github.com/kevachat/webapp.git
synced 2025-01-11 07:18:03 +00:00
implement recursive mentions folding tree
This commit is contained in:
parent
df9e860314
commit
0aca404bc0
@ -95,36 +95,32 @@ main ul
|
||||
|
||||
main ul ul
|
||||
{
|
||||
margin-bottom: 16px;
|
||||
margin-left: 16px;
|
||||
margin-top: 16px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
main ul > li
|
||||
main ul li
|
||||
{
|
||||
margin: 8px 0;
|
||||
padding: 8px 0;
|
||||
border-top: 1px var(--color-default) solid;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
main ul li > span > svg
|
||||
main ul li span > svg
|
||||
{
|
||||
cursor: default;
|
||||
fill: var(--color-default);
|
||||
|
@ -103,15 +103,24 @@ class RoomController extends AbstractController
|
||||
// Require valid kevachat meta
|
||||
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,
|
||||
'user' => $data->user,
|
||||
'icon' => $data->icon,
|
||||
'message' => $data->message,
|
||||
'timestamp' => $data->time,
|
||||
'time' => date('c', $data->time),
|
||||
'pending' => true
|
||||
'id' => $data->id,
|
||||
'user' => $data->user,
|
||||
'icon' => $data->icon,
|
||||
'time' => $data->time,
|
||||
'parent' => isset($mention[1]) ? $mention[1] : null,
|
||||
'message' => trim(
|
||||
preg_replace( // remove mention from folded message
|
||||
'/^@([A-z0-9]{64})\s/i',
|
||||
'',
|
||||
$data->message
|
||||
)
|
||||
),
|
||||
'pending' => true
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -128,15 +137,24 @@ class RoomController extends AbstractController
|
||||
// Require valid kevachat meta
|
||||
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,
|
||||
'user' => $data->user,
|
||||
'icon' => $data->icon,
|
||||
'message' => $data->message,
|
||||
'timestamp' => $data->time,
|
||||
'time' => date('c', $data->time),
|
||||
'pending' => false
|
||||
'id' => $data->id,
|
||||
'user' => $data->user,
|
||||
'icon' => $data->icon,
|
||||
'time' => $data->time,
|
||||
'parent' => isset($mention[1]) ? $mention[1] : null,
|
||||
'message' => trim(
|
||||
preg_replace( // remove mention from folded message
|
||||
'/^@([A-z0-9]{64})\s/i',
|
||||
'',
|
||||
$data->message
|
||||
)
|
||||
),
|
||||
'pending' => false
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -151,6 +169,14 @@ class RoomController extends AbstractController
|
||||
$feed
|
||||
);
|
||||
|
||||
// Init folding &data pool
|
||||
$fold = $feed;
|
||||
|
||||
// Build threading tree
|
||||
$tree = $this->_tree(
|
||||
$fold
|
||||
);
|
||||
|
||||
// RSS
|
||||
if ('rss' === $request->get('feed'))
|
||||
{
|
||||
@ -176,6 +202,7 @@ class RoomController extends AbstractController
|
||||
'default/room/index.html.twig',
|
||||
[
|
||||
'feed' => $feed,
|
||||
'tree' => $tree,
|
||||
'request' => $request
|
||||
]
|
||||
);
|
||||
@ -440,4 +467,36 @@ class RoomController extends AbstractController
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,3 +1,49 @@
|
||||
{% macro recursive_post_tree(namespace, tree) %}
|
||||
{% import _self as self %}
|
||||
{% if tree | length %}
|
||||
<ul>
|
||||
{% for post in tree %}
|
||||
<li>
|
||||
<div>
|
||||
<a name="{{ post.id }}"></a>
|
||||
{% if post.icon %}
|
||||
<img src="{{ post.icon }}" alt="icon" />
|
||||
{% else %}
|
||||
<strong>
|
||||
@{{ 'anon' | trans }}
|
||||
</strong>
|
||||
{% endif %}
|
||||
•
|
||||
<a rel="nofollow" href="{{ path('room_namespace', { namespace : namespace }) }}#{{ post.id }}" title="{{ post.time | date('c') }}">{{ post.time | format_ago }}</a>
|
||||
•
|
||||
<a rel="nofollow" href="{{ path('room_namespace', { namespace : namespace, txid : post.id }) }}#{{ post.id }}">{{ 'reply' | trans }}</a>
|
||||
{% if post.pending %}
|
||||
<span title="{{ 'pending in pool' | trans }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
|
||||
</svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
{# apply markdown whitelist filters only to prevent ping from remote includes #}
|
||||
{{
|
||||
post.message | striptags
|
||||
| markdown_to_html
|
||||
| striptags
|
||||
| message_to_markdown
|
||||
| trim
|
||||
| nl2br
|
||||
| markdown_to_html
|
||||
}}
|
||||
</div>
|
||||
{% if post.tree | length %}
|
||||
{{ self.recursive_post_tree(namespace, post.tree) }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</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 %}
|
||||
@ -11,46 +57,14 @@
|
||||
)
|
||||
)
|
||||
}}
|
||||
{% if feed %}
|
||||
<ul>
|
||||
{% for post in feed %}
|
||||
<li>
|
||||
<a name="{{ post.id }}"></a>
|
||||
{% if post.icon %}
|
||||
<img src="{{ post.icon }}" alt="icon" />
|
||||
{% else %}
|
||||
<strong>
|
||||
@{{ 'anon' | trans }}
|
||||
</strong>
|
||||
{% endif %}
|
||||
•
|
||||
<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 : request.get('namespace'), txid : post.id }) }}#{{ post.id }}">{{ 'reply' | trans }}</a>
|
||||
{% if post.pending %}
|
||||
<span title="{{ 'pending in pool' | trans }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z"/>
|
||||
</svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
{# apply markdown whitelist filters only to prevent ping from remote includes #}
|
||||
{{
|
||||
post.message | striptags
|
||||
| markdown_to_html
|
||||
| striptags
|
||||
| message_to_markdown
|
||||
| trim
|
||||
| nl2br
|
||||
| markdown_to_html
|
||||
}}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% if tree %}
|
||||
{{ recursive_post_tree(request.get('namespace'), tree) }}
|
||||
{% else %}
|
||||
<ul>
|
||||
<li>
|
||||
{{ 'room does not contain kevachat messages' | trans }}
|
||||
<div>
|
||||
{{ 'room does not contain kevachat messages' | trans }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
Loading…
Reference in New Issue
Block a user