Browse Source

implement basic features

main
ghost 7 months ago
parent
commit
fb9de3cf1b
  1. 30
      .env
  2. 1
      composer.json
  3. 1
      config/bundles.php
  4. 10
      config/packages/twig.yaml
  5. 11
      config/services.yaml
  6. 105
      public/css/default.css
  7. 91
      src/Controller/ModuleController.php
  8. 122
      src/Controller/RoomController.php
  9. 33
      templates/default/layout.html.twig
  10. 14
      templates/default/module/info.html.twig
  11. 22
      templates/default/module/post.html.twig
  12. 3
      templates/default/module/room.html.twig
  13. 25
      templates/default/room/index.html.twig

30
.env

@ -18,3 +18,33 @@ @@ -18,3 +18,33 @@
APP_ENV=dev
APP_SECRET=EDIT_ME
###< symfony/framework-bundle ###
APP_VERSION=1.0.0
APP_NAME=KevaChat
# Connect kevacoin
APP_KEVACOIN_PROTOCOL=http
APP_KEVACOIN_HOST=127.0.0.1
APP_KEVACOIN_PORT=9992
APP_KEVACOIN_USERNAME=EDIT_ME
APP_KEVACOIN_PASSWORD=EDIT_ME
# Default room namespace (must be owned to accept posts)
APP_KEVACOIN_NAMESPACE=EDIT_ME
# Address to receive kevacoin powers (make others able to fill node balance)
APP_KEVACOIN_ADDRESS=EDIT_ME
# Share with other some mining pool to get coins
APP_KEVACOIN_POOL_URL=https://kevacoin.hashvault.pro
# Allow remotes to create new rooms (namespaces)
APP_ADD_ROOM_REMOTE_IP_REGEX=/.*/
# Allow remotes to create new posts (submit key/values)
APP_ADD_POST_REMOTE_IP_REGEX=/.*/
# Time quota for remote publications by IP (seconds)
APP_ADD_POST_REMOTE_IP_DELAY=60

1
composer.json

@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
"symfony/flex": "^2",
"symfony/framework-bundle": "7.0.*",
"symfony/runtime": "7.0.*",
"symfony/twig-bundle": "7.0.*",
"symfony/yaml": "7.0.*"
},
"config": {

1
config/bundles.php

@ -2,4 +2,5 @@ @@ -2,4 +2,5 @@
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
];

10
config/packages/twig.yaml

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
twig:
default_path: '%kernel.project_dir%/templates'
globals:
app:
version: '%app.version%'
name: '%app.name%'
when@test:
twig:
strict_variables: true

11
config/services.yaml

@ -4,6 +4,17 @@ @@ -4,6 +4,17 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
app.version: '%env(APP_VERSION)%'
app.name: '%env(APP_NAME)%'
app.kevacoin.protocol: '%env(APP_KEVACOIN_PROTOCOL)%'
app.kevacoin.host: '%env(APP_KEVACOIN_HOST)%'
app.kevacoin.port: '%env(APP_KEVACOIN_PORT)%'
app.kevacoin.username: '%env(APP_KEVACOIN_USERNAME)%'
app.kevacoin.password: '%env(APP_KEVACOIN_PASSWORD)%'
app.kevacoin.namespace: '%env(APP_KEVACOIN_NAMESPACE)%'
app.kevacoin.address: '%env(APP_KEVACOIN_ADDRESS)%'
app.kevacoin.pool.url: '%env(APP_KEVACOIN_POOL_URL)%'
services:
# default configuration for services in *this* file

105
public/css/default.css

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
*
{
/* apply defaults */
margin: 0;
padding: 0;
/* allow draw */
font-family: monospace;
/* adaptive */
color-scheme: light dark;
/* vars */
--container-max-width: 740px;
}
*::placeholder
{
font-size: 12px;
}
a, a:active, a:visited
{
text-decoration: none;
}
a:hover
{
text-decoration: underline;
}
body
{
font-size: 12px;
padding: 0 16px;
}
header
{
max-width: var(--container-max-width);
margin: 16px auto;
display: block;
}
header > strong
{
font-size: 14px;
}
header > div
{
margin: 8px 0;
}
header > div > pre
{
display: inline-block;
}
main
{
max-width: var(--container-max-width);
margin: 16px auto;
display: block;
}
main > form > input[type="text"]
{
box-sizing: border-box;
padding: 4px;
width: 100%;
}
footer
{
display: block;
margin: 16px auto;
max-width: var(--container-max-width);
}
footer > form
{
bottom: 16px;
display: block;
max-width: var(--container-max-width);
position: fixed;
width: 100%;
}
footer > form > textarea
{
box-sizing: border-box;
display: block;
margin: 8px 0;
max-width: var(--container-max-width);
padding: 4px;
width: 100%;
}
footer > form > button
{
cursor: pointer;
float: right;
padding: 2px 8px;
}

91
src/Controller/ModuleController.php

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class ModuleController extends AbstractController
{
public function info(): Response
{
$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')
);
return $this->render(
'default/module/info.html.twig',
[
'wallet' =>
[
'balance' => (float) $client->getBalance(),
'block' => (int) $client->getBlockCount(),
'address' => $this->getParameter('app.kevacoin.address')
],
'pool' => [
'url' => $this->getParameter('app.kevacoin.pool.url')
]
]
);
}
public function room(
Request $request
): Response
{
$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')
);
return $this->render(
'default/module/room.html.twig',
[
'room' => $request->get('room'),
'list' => (array) $client->kevaListNamespaces()
]
);
}
public function post(
Request $request
): Response
{
$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 wallet namespaces (to enable post module there)
$namespaces = [];
foreach ((array) $client->kevaListNamespaces() as $key => $value)
{
$namespaces[] = $key;
}
return $this->render(
'default/module/post.html.twig',
[
'enabled' => in_array($request->get('namespace'), $namespaces),
'namespace' => $request->get('namespace'),
'message' => $request->get('message'),
'user' => $request->get('user'),
'ip' => $request->getClientIp()
]
);
}
}

122
src/Controller/RoomController.php

@ -0,0 +1,122 @@ @@ -0,0 +1,122 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class RoomController extends AbstractController
{
#[Route(
'/',
name: 'room_index',
methods:
[
'GET'
]
)]
public function index(): Response
{
return $this->redirectToRoute(
'room_namespace',
[
'namespace' => $this->getParameter('app.kevacoin.namespace')
]
);
}
#[Route(
'/room/{namespace}',
name: 'room_namespace',
requirements:
[
'namespace' => '^[A-z0-9]{34}$',
],
methods:
[
'GET'
]
)]
public function room(
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 messages
$messages = [];
foreach ((array) $client->kevaFilter($request->get('namespace')) as $message)
{
$messages[] = $message;
}
// Return result
return $this->render(
'default/room/index.html.twig',
[
'messages' => $messages,
'request' => $request
]
);
}
#[Route(
'/room/{namespace}/post',
name: 'room_post',
requirements:
[
'namespace' => '^[A-z0-9]{34}$',
],
methods:
[
'POST'
]
)]
public function post(
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')
);
// Check namespace exist for this wallet
$namespaces = [];
foreach ((array) $client->kevaListNamespaces() as $key => $value)
{
$namespaces[] = $key;
}
if (!in_array($request->get('namespace'), $namespaces))
{
exit('Namespace not related with this node!');
}
// @TODO
// Redirect back to the room
return $this->redirectToRoute(
'room_namespace',
[
'namespace' => $this->getParameter('app.kevacoin.namespace')
]
);
}
}

33
templates/default/layout.html.twig

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block head_title %}{{ 'KevaChat' | trans }}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="/css/default.css?{{ app.version }}"/>
</head>
<body>
<header>
<strong>
{{ app.name }}
</strong>
<sup>
<a href="https://github.com/kevachat/webapp" target="_blank" title="Source">{{ app.version }}</a>
</sup>
{% block header_module_info %}
{{
render(
controller(
'App\\Controller\\ModuleController::info'
)
)
}}
{% endblock %}
</header>
<main>
{% block main_content %}{% endblock %}
</main>
<footer>
{% block footer_content %}{% endblock %}
</footer>
</body>
</html>

14
templates/default/module/info.html.twig

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
<div>
{{ 'Block:' | trans }} {{ wallet.block }}
/
{{ 'Balance:' | trans }} {{ wallet.balance }}
{% if wallet.address %}
/
{% if pool.url %}
<a href="{{ pool.url }}" target="_blank">{{ 'Charge' | trans }}</a>:
{% else %}
{{ 'Charge:' | trans }}
{% endif %}
<pre>{{ wallet.address }}</pre>
{% endif %}
</div>

22
templates/default/module/post.html.twig

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
{% if enabled %}
<form name="post" action="{{ path('room_post', { namespace : namespace }) }}" method="post">
<textarea name="message" placeholder="{{ 'enter your message...' | trans }}">{{ message }}</textarea>
{% if user == 'anonymous' or user != 'ip' %}
<input type="radio" name="user" value="anonymous" id="form-post-user-anonymous" checked="checked" />
{% else %}
<input type="radio" name="user" value="anonymous" id="form-post-user-anonymous" />
{% endif %}
<label for="form-post-user-anonymous">
{{ 'anonymous' | trans }}
</label>
{% if user == 'ip' %}
<input type="radio" name="user" value="ip" id="form-post-user-ip" checked="checked" />
{% else %}
<input type="radio" name="user" value="ip" id="form-post-user-ip" />
{% endif %}
<label for="form-post-user-ip">
@{{ ip }}
</label>
<button type="submit">{{ 'send' | trans }}</button>
</form>
{% endif %}

3
templates/default/module/room.html.twig

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
<form name="room" action="{{ path('room_index') }}" method="get">
<input type="text" name="room" value="{{ room }}" placeholder="{{ 'join room by kevacoin namespace...' | trans }}" />
</form>

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

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
{% extends 'default/layout.html.twig' %}
{% block main_content %}
{{
render(
controller(
'App\\Controller\\ModuleController::room',
{
request: request
}
)
)
}}
{% endblock %}
{% block footer_content %}
{{
render(
controller(
'App\\Controller\\ModuleController::post',
{
request: request
}
)
)
}}
{% endblock %}
Loading…
Cancel
Save