mirror of
https://github.com/kevachat/webapp.git
synced 2025-01-08 22:07:53 +00:00
implement basic features
This commit is contained in:
parent
a03a9d83a5
commit
fb9de3cf1b
30
.env
30
.env
@ -18,3 +18,33 @@
|
|||||||
APP_ENV=dev
|
APP_ENV=dev
|
||||||
APP_SECRET=EDIT_ME
|
APP_SECRET=EDIT_ME
|
||||||
###< symfony/framework-bundle ###
|
###< 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
|
@ -13,6 +13,7 @@
|
|||||||
"symfony/flex": "^2",
|
"symfony/flex": "^2",
|
||||||
"symfony/framework-bundle": "7.0.*",
|
"symfony/framework-bundle": "7.0.*",
|
||||||
"symfony/runtime": "7.0.*",
|
"symfony/runtime": "7.0.*",
|
||||||
|
"symfony/twig-bundle": "7.0.*",
|
||||||
"symfony/yaml": "7.0.*"
|
"symfony/yaml": "7.0.*"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||||
|
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
10
config/packages/twig.yaml
Normal file
10
config/packages/twig.yaml
Normal file
@ -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
|
@ -4,6 +4,17 @@
|
|||||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
# 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
|
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||||
parameters:
|
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:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
105
public/css/default.css
Normal file
105
public/css/default.css
Normal file
@ -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
Normal file
91
src/Controller/ModuleController.php
Normal file
@ -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
Normal file
122
src/Controller/RoomController.php
Normal file
@ -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
Normal file
33
templates/default/layout.html.twig
Normal file
@ -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
Normal file
14
templates/default/module/info.html.twig
Normal file
@ -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
Normal file
22
templates/default/module/post.html.twig
Normal file
@ -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
Normal file
3
templates/default/module/room.html.twig
Normal file
@ -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
Normal file
25
templates/default/room/index.html.twig
Normal file
@ -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…
Reference in New Issue
Block a user