Browse Source

implement rooms list

main
ghost 7 months ago
parent
commit
5ffd0a3bc2
  1. 7
      .env
  2. 4
      README.md
  3. 3
      config/services.yaml
  4. 2
      public/css/default.css
  5. 11
      src/Controller/ModuleController.php
  6. 126
      src/Controller/RoomController.php
  7. 15
      templates/default/module/rooms.html.twig
  8. 2
      templates/default/room/index.html.twig
  9. 46
      templates/default/room/list.html.twig
  10. 16
      templates/default/room/list.rss.twig

7
.env

@ -50,17 +50,14 @@ APP_KEVACOIN_EXPLORER_URL=https://keva.one/explorer/address/
APP_KEVACOIN_BOOST_ADDRESS=EDIT_ME APP_KEVACOIN_BOOST_ADDRESS=EDIT_ME
# Allowed room namespaces, separated with | (must be owned to accept posts) # Allowed room namespaces, separated with | (must be owned to accept posts)
APP_KEVACOIN_ROOM_NAMESPACES=EDIT_ME APP_KEVACOIN_ROOM_NAMESPACES_PINNED=EDIT_ME
# Allowed room namespaces for read only (e.g. project news) separated with | # Allowed room namespaces for read only (e.g. project news) separated with |
APP_KEVACOIN_ROOM_NAMESPACES_READONLY=EDIT_ME APP_KEVACOIN_ROOM_NAMESPACES_READONLY=
# Redirect from index page to default room # Redirect from index page to default room
APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT=EDIT_ME APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT=EDIT_ME
# Allow users to read external node rooms
APP_KEVACOIN_ROOM_NAMESPACES_EXTERNAL=
# Online session expiration timeout # Online session expiration timeout
APP_SESSION_ONLINE_TIMEOUT=900 APP_SESSION_ONLINE_TIMEOUT=900

4
README.md

@ -47,8 +47,8 @@ Application package contain settings preset, just few steps required to launch:
* Copy `rpcuser` to `env`.`APP_KEVACOIN_USERNAME` and `rpcpassword` to `env`.`APP_KEVACOIN_PASSWORD` * Copy `rpcuser` to `env`.`APP_KEVACOIN_USERNAME` and `rpcpassword` to `env`.`APP_KEVACOIN_PASSWORD`
* Generate new address using CLI `kevacoin-cli getnewaddress` and copy to `env`.`APP_KEVACOIN_BOOST_ADDRESS` * Generate new address using CLI `kevacoin-cli getnewaddress` and copy to `env`.`APP_KEVACOIN_BOOST_ADDRESS`
* Send few coins to this address and wait for new block to continue * Send few coins to this address and wait for new block to continue
* Create namespace for the chat room with `kevacoin-cli keva_namespace "sandbox"` and add it hash to `env`.`APP_KEVACOIN_ROOM_NAMESPACES` * Create at least one room namespace with Web UI or CLI `kevacoin-cli keva_namespace "sandbox"`
* Also Provide at least one namespace for default chat room to `env`.`APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT` (for homepage redirects) * Provide at least one namespace for default chat room to `env`.`APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT` (for homepage redirects)
## Contribution ## Contribution

3
config/services.yaml

@ -15,9 +15,8 @@ parameters:
app.kevacoin.port: '%env(APP_KEVACOIN_PORT)%' app.kevacoin.port: '%env(APP_KEVACOIN_PORT)%'
app.kevacoin.username: '%env(APP_KEVACOIN_USERNAME)%' app.kevacoin.username: '%env(APP_KEVACOIN_USERNAME)%'
app.kevacoin.password: '%env(APP_KEVACOIN_PASSWORD)%' app.kevacoin.password: '%env(APP_KEVACOIN_PASSWORD)%'
app.kevacoin.room.namespaces: '%env(APP_KEVACOIN_ROOM_NAMESPACES)%' app.kevacoin.room.namespaces.pinned: '%env(APP_KEVACOIN_ROOM_NAMESPACES_PINNED)%'
app.kevacoin.room.namespaces.readonly: '%env(APP_KEVACOIN_ROOM_NAMESPACES_READONLY)%' app.kevacoin.room.namespaces.readonly: '%env(APP_KEVACOIN_ROOM_NAMESPACES_READONLY)%'
app.kevacoin.room.namespaces.external: '%env(APP_KEVACOIN_ROOM_NAMESPACES_EXTERNAL)%'
app.kevacoin.room.namespace.default: '%env(APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT)%' app.kevacoin.room.namespace.default: '%env(APP_KEVACOIN_ROOM_NAMESPACE_DEFAULT)%'
app.kevacoin.boost.address: '%env(APP_KEVACOIN_BOOST_ADDRESS)%' app.kevacoin.boost.address: '%env(APP_KEVACOIN_BOOST_ADDRESS)%'
app.kevacoin.explorer.url: '%env(APP_KEVACOIN_EXPLORER_URL)%' app.kevacoin.explorer.url: '%env(APP_KEVACOIN_EXPLORER_URL)%'

2
public/css/default.css

@ -127,7 +127,7 @@ main ul li span > svg
float: right; float: right;
} }
main > sup > a > svg main a > svg
{ {
fill: var(--color-warning); fill: var(--color-warning);
} }

11
src/Controller/ModuleController.php

@ -95,7 +95,7 @@ class ModuleController extends AbstractController
); );
} }
public function room( public function rooms(
Request $request Request $request
): Response ): Response
{ {
@ -108,9 +108,9 @@ class ModuleController extends AbstractController
); );
return $this->render( return $this->render(
'default/module/room.html.twig', 'default/module/rooms.html.twig',
[ [
'list' => (array) explode('|', $this->getParameter('app.kevacoin.room.namespaces')), 'list' => (array) explode('|', $this->getParameter('app.kevacoin.room.namespaces.pinned')),
'form' => 'form' =>
[ [
'namespace' => 'namespace' =>
@ -168,11 +168,6 @@ class ModuleController extends AbstractController
'enabled' => 'enabled' =>
( (
in_array(
$request->get('namespace'),
explode('|', $this->getParameter('app.kevacoin.room.namespaces'))
)
&&
!in_array( !in_array(
$request->get('namespace'), $request->get('namespace'),
explode('|', $this->getParameter('app.kevacoin.room.namespaces.readonly')) explode('|', $this->getParameter('app.kevacoin.room.namespaces.readonly'))

126
src/Controller/RoomController.php

@ -31,6 +31,106 @@ class RoomController extends AbstractController
); );
} }
#[Route(
'/room/list',
name: 'room_list',
methods:
[
'GET'
]
)]
public function list(
?Request $request
): Response
{
// Connect kevacoin
$client = new \Kevachat\Kevacoin\Client(
$this->getParameter('app.kevacoin.protocol'),
$this->getParameter('app.kevacoin.host'),
$this->getParameter('app.kevacoin.port'),
$this->getParameter('app.kevacoin.username'),
$this->getParameter('app.kevacoin.password')
);
// Get room list
$list = [];
foreach ((array) $client->kevaListNamespaces() as $value)
{
// Calculate room totals
$total = 0;
foreach ((array) $client->kevaFilter($value['namespaceId']) as $post)
{
// Skip values with meta keys
if (false !== stripos($post['key'], '_KEVA_'))
{
continue;
}
// Require valid kevachat meta
if ($this->_post($post))
{
$total++;
}
}
// Add to room list
$list[] =
[
'namespace' => $value['namespaceId'],
'name' => $value['displayName'],
'total' => $total,
'pinned' => in_array(
$value['namespaceId'],
(array) explode(
'|',
$this->getParameter('app.kevacoin.room.namespaces.pinned')
)
)
];
}
// Sort by name
array_multisort(
array_column(
$list,
'name'
),
SORT_ASC,
$list
);
// RSS
if ('rss' === $request->get('feed'))
{
$response = new Response();
$response->headers->set(
'Content-Type',
'text/xml'
);
return $this->render(
'default/room/list.rss.twig',
[
'list' => $list,
'request' => $request
],
$response
);
}
// HTML
return $this->render(
'default/room/list.html.twig',
[
'list' => $list,
'request' => $request
]
);
}
#[Route( #[Route(
'/room/{namespace}/{txid}', '/room/{namespace}/{txid}',
name: 'room_namespace', name: 'room_namespace',
@ -61,21 +161,6 @@ class RoomController extends AbstractController
$this->getParameter('app.kevacoin.password') $this->getParameter('app.kevacoin.password')
); );
// Check for external rooms reading allowed in config
if (
!in_array(
$request->get('namespace'),
(array) explode('|', $this->getParameter('app.kevacoin.room.namespaces'))
)
&&
$this->getParameter('app.kevacoin.room.namespaces.external')
) {
// @TODO process to error page instead of redirect to default room
return $this->redirectToRoute(
'room_index'
);
}
// Get room feed // Get room feed
$feed = []; $feed = [];
@ -263,14 +348,21 @@ class RoomController extends AbstractController
); );
// Check namespace defined in config // Check namespace defined in config
if (!in_array($request->get('namespace'), (array) explode('|', $this->getParameter('app.kevacoin.room.namespaces')))) $rooms = [];
foreach ((array) $client->kevaListNamespaces() as $value)
{
$rooms[] = $value['namespaceId'];
}
if (!in_array($request->get('namespace'), $rooms))
{ {
return $this->redirectToRoute( return $this->redirectToRoute(
'room_namespace', 'room_namespace',
[ [
'namespace' => $request->get('namespace'), 'namespace' => $request->get('namespace'),
'message' => $request->get('message'), 'message' => $request->get('message'),
'error' => $translator->trans('Namespace not listed in settings!') 'error' => $translator->trans('Namespace not not found on this node!')
] ]
); );
} }

15
templates/default/module/room.html.twig → templates/default/module/rooms.html.twig

@ -17,4 +17,19 @@
</svg></a> </svg></a>
</sup> </sup>
{% endfor %} {% endfor %}
{% endif %}
{% if list %}
&bull;
<h2>
{% if form.namespace.value %}
<a href="{{ path('room_list') }}">{{ 'all' | trans }}</a>
{% else %}
{{ 'all' | trans }}
{% endif %}
</h2>
<sup>
<a href="{{ path('room_list', { feed : 'rss' }) }}" title="{{ 'RSS' | trans }}" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm1.5 2.5c5.523 0 10 4.477 10 10a1 1 0 1 1-2 0 8 8 0 0 0-8-8 1 1 0 0 1 0-2m0 4a6 6 0 0 1 6 6 1 1 0 1 1-2 0 4 4 0 0 0-4-4 1 1 0 0 1 0-2m.5 7a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3"/>
</svg></a>
</sup>
{% endif %} {% endif %}

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

@ -50,7 +50,7 @@
{{ {{
render( render(
controller( controller(
'App\\Controller\\ModuleController::room', 'App\\Controller\\ModuleController::rooms',
{ {
request: request request: request
} }

46
templates/default/room/list.html.twig

@ -0,0 +1,46 @@
{% extends 'default/layout.html.twig' %}
{% block head_title_content %}{{ 'Rooms' | trans }} - {{ 'KevaChat' | trans }}{% endblock %}
{% block main_content %}
{{
render(
controller(
'App\\Controller\\ModuleController::rooms',
{
request: request
}
)
)
}}
{% if list | length %}
<ul>
{% for room in list %}
<li>
<div>
<strong>
<a href="{{ path('room_namespace', { namespace : room.namespace }) }}">{{ room.namespace | keva_namespace_value }}</a>
</strong>
{{ room.total }}
<a href="{{ path('room_namespace', { namespace : room.namespace, feed : 'rss' }) }}" title="{{ 'RSS' | trans }}" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm1.5 2.5c5.523 0 10 4.477 10 10a1 1 0 1 1-2 0 8 8 0 0 0-8-8 1 1 0 0 1 0-2m0 4a6 6 0 0 1 6 6 1 1 0 1 1-2 0 4 4 0 0 0-4-4 1 1 0 0 1 0-2m.5 7a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3"/>
</svg></a>
{% if room.pinned %}
<i title="{{ 'pinned' | trans }}">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16" title="{{ 'pinned' | trans }}" style="float:right">
<path d="M9.828.722a.5.5 0 0 1 .354.146l4.95 4.95a.5.5 0 0 1 0 .707c-.48.48-1.072.588-1.503.588-.177 0-.335-.018-.46-.039l-3.134 3.134a5.927 5.927 0 0 1 .16 1.013c.046.702-.032 1.687-.72 2.375a.5.5 0 0 1-.707 0l-2.829-2.828-3.182 3.182c-.195.195-1.219.902-1.414.707-.195-.195.512-1.22.707-1.414l3.182-3.182-2.828-2.829a.5.5 0 0 1 0-.707c.688-.688 1.673-.767 2.375-.72a5.922 5.922 0 0 1 1.013.16l3.134-3.133a2.772 2.772 0 0 1-.04-.461c0-.43.108-1.022.589-1.503a.5.5 0 0 1 .353-.146z"/>
</svg>
</i>
{% endif %}
</div>
</li>
{% endfor %}
</ul>
{% else %}
<ul>
<li>
<div>
{{ 'rooms not found' | trans }}
</div>
</li>
</ul>
{% endif %}
{% endblock %}

16
templates/default/room/list.rss.twig

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<atom:link href="{{ url('room_list') }}" rel="self" type="application/rss+xml"></atom:link>
<title>{{ 'Rooms' | trans }} - {{ 'KevaChat' | trans }}</title>
<link>{{ url('room_list') }}</link>
{% for room in list %}
<item>
<title>{{ room.namespace | keva_namespace_value }}</title>
<guid>{{ url('room_namespace', { namespace : room.namespace }) }}</guid>
<link>{{ url('room_namespace', { namespace : room.namespace }) }}</link>
<description>{{ 'join' | trans }} {{ room.namespace | keva_namespace_value }} {{ 'room' | trans }}!</description>
</item>
{% endfor %}
</channel>
</rss>
Loading…
Cancel
Save