mirror of
https://github.com/YunoHost-Apps/minchat_ynh.git
synced 2024-09-03 19:36:29 +02:00
Creation
This commit is contained in:
parent
8bd60d3aba
commit
2d3d716f61
15 changed files with 638 additions and 0 deletions
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Chtixof
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
18
README.md
Normal file
18
README.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# minchat_ynh : minchat for Yunohost
|
||||
|
||||
minchat_ynh is a free minimalist chat application packaged for [Yunohost](https://yunohost.org).
|
||||
It is based on [wojtek77/chat](https://github.com/wojtek77/chat), itself based on [Gabriel Nava's tutorial](http://code.tutsplus.com/tutorials/how-to-create-a-simple-web-based-chat-application--net-5931).
|
||||
|
||||
## Features
|
||||
|
||||
- No need for users to register. Just need the web address.
|
||||
- On connection, the page is feeded with the 50 last messages.
|
||||
- Optional *get* arguments to specify the user name and the room. Example : ...minchat/?name=John&room=Living
|
||||
- Mono room (for now)
|
||||
|
||||
## Installation
|
||||
### On Yunohost
|
||||
Via the admin web console, type in: <https://github.com/chtixof/minchat_ynh>
|
||||
Or on ssh : `sudo yunohost app install https://github.com/chtixof/minchat_ynh`
|
||||
### Otherwise
|
||||
Download, unzip and just copy the content of the `source` folder to any folder of your web site.
|
18
conf/nginx.conf
Normal file
18
conf/nginx.conf
Normal file
|
@ -0,0 +1,18 @@
|
|||
location PATHTOCHANGE {
|
||||
|
||||
alias WWWPATH ;
|
||||
|
||||
index index.html index.php ;
|
||||
try_files $uri $uri/ index.php;
|
||||
location ~ [^/]\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param REMOTE_USER $remote_user;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
}
|
||||
|
||||
# Include SSOWAT user panel.
|
||||
include conf.d/yunohost_panel.conf.inc;
|
||||
}
|
39
manifest.json
Normal file
39
manifest.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "minchat",
|
||||
"id": "minchat",
|
||||
"description": {
|
||||
"en": "A minimalist web chat",
|
||||
"fr": "Un web chat minimaliste"
|
||||
},
|
||||
"license": "MIT",
|
||||
"developer": {
|
||||
"name": "chtixof"
|
||||
},
|
||||
"multi_instance": "false",
|
||||
"arguments": {
|
||||
"install" : [ {
|
||||
"name": "domain",
|
||||
"ask": {
|
||||
"en": "Choose a domain for minchat",
|
||||
"en": "Choisissez un domaine pour minchat"
|
||||
},
|
||||
"example": "domain.org"
|
||||
},{
|
||||
"name": "path",
|
||||
"ask": {
|
||||
"en": "Choose a path for minchat",
|
||||
"en": "Choisissez un chemin pour minchat"
|
||||
},
|
||||
"example": "/minchat",
|
||||
"default": "/minchat"
|
||||
},{
|
||||
"name": "ispublic",
|
||||
"ask": {
|
||||
"en": "Is it a public site (Y)",
|
||||
"en": "Taper Y si le site est public"
|
||||
},
|
||||
"example": "Y",
|
||||
"default": "Y"
|
||||
} ]
|
||||
}
|
||||
}
|
15
scripts/backup
Normal file
15
scripts/backup
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
app=minchat
|
||||
|
||||
# The parameter $1 is the backup directory location
|
||||
# which will be compressed afterward
|
||||
backup_dir=$1/apps/$app
|
||||
mkdir -p $backup_dir
|
||||
|
||||
# Backup sources & data
|
||||
sudo cp -a /var/www/$app/. $backup_dir/sources
|
||||
|
||||
# Copy Nginx and YunoHost parameters to make the script "standalone"
|
||||
sudo cp -a /etc/yunohost/apps/$app/. $backup_dir/yunohost
|
||||
domain=$(sudo yunohost app setting $app domain)
|
||||
sudo cp -a /etc/nginx/conf.d/$domain.d/$app.conf $backup_dir/nginx.conf
|
35
scripts/install
Normal file
35
scripts/install
Normal file
|
@ -0,0 +1,35 @@
|
|||
#!/bin/bash
|
||||
# Installation de minchat dans Yunohost
|
||||
app=minchat
|
||||
|
||||
# Retrieve arguments
|
||||
domain=$1
|
||||
path=$2
|
||||
is_public=$3
|
||||
|
||||
# Check domain/path availability
|
||||
sudo yunohost app checkurl $domain$path -a $app
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copy files to the right place with the right permissions
|
||||
final_path=/var/www/$app
|
||||
sudo mkdir -p $final_path
|
||||
sudo cp -a ../sources/* $final_path
|
||||
sudo chown -R www-data: $final_path
|
||||
|
||||
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
|
||||
sed -i "s@WWWPATH@$final_path@g" ../conf/nginx.conf
|
||||
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||
|
||||
# Make it public is required
|
||||
if [[ $is_public =~ ^[Yy]$ ]]
|
||||
then
|
||||
sudo yunohost app setting $app skipped_uris -v "/"
|
||||
fi
|
||||
|
||||
# Reload nginx and regenerate SSOwat conf
|
||||
sudo service nginx reload
|
||||
sudo yunohost app ssowatconf
|
15
scripts/remove
Normal file
15
scripts/remove
Normal file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/bash
|
||||
app=minchat
|
||||
|
||||
# Retrieve arguments
|
||||
domain=$(sudo yunohost app setting $app domain)
|
||||
|
||||
# Remove sources
|
||||
sudo rm -rf /var/www/$app
|
||||
|
||||
# Remove configuration files
|
||||
sudo rm -f /etc/nginx/conf.d/$domain.d/$app.conf
|
||||
|
||||
# Restart services
|
||||
sudo service nginx reload
|
||||
sudo yunohost app ssowatconf
|
16
scripts/restore
Normal file
16
scripts/restore
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
app=minchat
|
||||
|
||||
# The parameter $1 is the uncompressed restore directory location
|
||||
backup_dir=$1/apps/$app
|
||||
|
||||
# Restore sources & data
|
||||
sudo cp -a $backup_dir/sources/. /var/www/$app
|
||||
|
||||
# Restore Nginx and YunoHost parameters
|
||||
sudo cp -a $backup_dir/yunohost/. /etc/yunohost/apps/$app
|
||||
domain=$(sudo yunohost app setting $app domain)
|
||||
sudo cp -a $backup_dir/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||
|
||||
# Restart webserver
|
||||
sudo service nginx reload
|
24
scripts/upgrade
Normal file
24
scripts/upgrade
Normal file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
app=minchat
|
||||
|
||||
# Retrieve arguments
|
||||
domain=$(sudo yunohost app setting $app domain)
|
||||
path=$(sudo yunohost app setting $app path)
|
||||
|
||||
# Remove trailing "/" for next commands
|
||||
path=${path%/}
|
||||
|
||||
# Copy source files
|
||||
final_path=/var/www/$app
|
||||
sudo mkdir -p $final_path
|
||||
sudo cp -a ../sources/* $final_path
|
||||
|
||||
# Modify Nginx configuration file and copy it to Nginx conf directory
|
||||
sed -i "s@PATHTOCHANGE@$path@g" ../conf/nginx.conf
|
||||
sed -i "s@WWWPATH@$final_path@g" ../conf/nginx.conf
|
||||
sudo cp ../conf/nginx.conf /etc/nginx/conf.d/$domain.d/$app.conf
|
||||
|
||||
# Restart services
|
||||
sudo service nginx reload
|
||||
sudo yunohost app ssowatconf
|
||||
|
173
sources/index.php
Normal file
173
sources/index.php
Normal file
|
@ -0,0 +1,173 @@
|
|||
<?php
|
||||
|
||||
function v($v, $czyscHtmlIExit = false) {
|
||||
if ($czyscHtmlIExit) ob_end_clean();
|
||||
echo '<pre>' . print_r($v, true) . '</pre>';
|
||||
if ($czyscHtmlIExit) exit;
|
||||
}
|
||||
function vv($v, $czyscHtmlIExit = false) {
|
||||
if ($czyscHtmlIExit) ob_end_clean();
|
||||
echo '<pre>';
|
||||
var_dump($v);
|
||||
echo '</pre>';
|
||||
if ($czyscHtmlIExit) exit;
|
||||
}
|
||||
function vvv($var, & $result = null, $is_view = true)
|
||||
{
|
||||
if (is_array($var) || is_object($var)) foreach ($var as $key=> $value) vvv($value, $result[$key], false);
|
||||
else $result = $var;
|
||||
|
||||
if ($is_view) v($result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function loginForm() {
|
||||
echo'
|
||||
<div id="loginform">
|
||||
<form action="" method="post">
|
||||
<p>Please enter your name to continue:</p>
|
||||
<label for="name">Name:</label>
|
||||
<input type="text" name="name" id="name"/>
|
||||
<input type="submit" name="enter" id="enter" value="Enter" />
|
||||
</form>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
function getSetup($key = null) {
|
||||
$arr = parse_ini_file('setup.ini');
|
||||
return isset($key) ? $arr[$key] : $arr;
|
||||
}
|
||||
|
||||
function deleteOldHistory() {
|
||||
$expireHistory = getSetup('expire_history');
|
||||
$expireDate = date('Y-m-d', strtotime("-$expireHistory day"));
|
||||
foreach (glob('./history/*') as $f) {
|
||||
if (basename($f) < $expireDate) {
|
||||
unlink($f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
|
||||
session_start();
|
||||
|
||||
if (isset($_GET['logout'])) {
|
||||
session_destroy();
|
||||
header("Location: ./"); //Redirect the user
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['name'])) {
|
||||
if ($_REQUEST['name'] != "") {
|
||||
$_SESSION['name'] = stripslashes(htmlspecialchars($_REQUEST['name']));
|
||||
} else {
|
||||
echo '<span class="error">Please type in a name</span>';
|
||||
}
|
||||
}
|
||||
if (isset($_REQUEST['room'])) {
|
||||
$room = $_REQUEST['room'];
|
||||
} else {
|
||||
$room = "";
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Chat - Customer Module</title>
|
||||
<link type="text/css" rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
|
||||
<?php
|
||||
if (!isset($_SESSION['name'])) {
|
||||
loginForm();
|
||||
deleteOldHistory();
|
||||
} else {
|
||||
?>
|
||||
<div id="wrapper">
|
||||
<div id="menu">
|
||||
<p class="welcome">Welcome to the <b><?php echo $room; ?></b> room, <b><?php echo $_SESSION['name']; ?></b></p>
|
||||
<div style="clear:both"></div>
|
||||
</div>
|
||||
<div id="chatbox"><?php
|
||||
?></div>
|
||||
|
||||
<form name="message" action="">
|
||||
<input name="usermsg" type="text" id="usermsg" size="63" autocomplete="off" autofocus/>
|
||||
<input name="submitmsg" type="submit" id="submitmsg" value="Send" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript" src="lib/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
// jQuery Document
|
||||
$(document).ready(function() {
|
||||
var id = 'undefined';
|
||||
//If user submits the form
|
||||
$("#submitmsg").click(function() {
|
||||
var clientmsg = $("#usermsg").val();
|
||||
$("#usermsg").val('');
|
||||
$("#usermsg").focus();
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'post.php',
|
||||
data: {text: clientmsg},
|
||||
//cache: false,
|
||||
async: false,
|
||||
success: function(data) {
|
||||
loadLog();
|
||||
},
|
||||
error: function(request, status, error) {
|
||||
$("#usermsg").val(clientmsg);
|
||||
},
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
//Load the file containing the chat log
|
||||
function loadLog() {
|
||||
var oldscrollHeight = $("#chatbox")[0].scrollHeight;
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'server.php',
|
||||
data: {id: id},
|
||||
dataType: 'json',
|
||||
//cache: false,
|
||||
async: false,
|
||||
success: function(data) {
|
||||
id = data.id;
|
||||
var html = '';
|
||||
var date;
|
||||
for (var k in data.data.reverse()) {
|
||||
date = new Date(parseInt(data.data[k][0])*1000);
|
||||
date = date.toLocaleTimeString();
|
||||
date = date.replace(/([\d]+\D+[\d]{2})\D+[\d]{2}(.*)/, '$1$2');
|
||||
html = html
|
||||
+"<div class='msgln'>("+date+") <b>"
|
||||
+data.data[k][1]+"</b>: "+data.data[k][2]+"<br></div>";
|
||||
}
|
||||
$("#chatbox").append(html); //Insert chat messages into the #chatbox div
|
||||
var newscrollHeight = $("#chatbox")[0].scrollHeight;
|
||||
if (newscrollHeight > oldscrollHeight) {
|
||||
$("#chatbox").scrollTop($("#chatbox")[0].scrollHeight);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
loadLog();
|
||||
setInterval(loadLog, <?php echo getSetup('interval') ?>); //Reload file every 2.5 seconds
|
||||
|
||||
//If user wants to end session
|
||||
$("#exit").click(function() {
|
||||
var exit = confirm("Are you sure you want to end the session?");
|
||||
if (exit == true) {
|
||||
window.location = 'index.php?logout=true';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
4
sources/lib/jquery-2.1.3.min.js
vendored
Normal file
4
sources/lib/jquery-2.1.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
103
sources/post.php
Normal file
103
sources/post.php
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
function v($v, $czyscHtmlIExit = false) {
|
||||
if ($czyscHtmlIExit) ob_end_clean();
|
||||
echo '<pre>' . print_r($v, true) . '</pre>';
|
||||
if ($czyscHtmlIExit) exit;
|
||||
}
|
||||
function vv($v, $czyscHtmlIExit = false) {
|
||||
if ($czyscHtmlIExit) ob_end_clean();
|
||||
echo '<pre>';
|
||||
var_dump($v);
|
||||
echo '</pre>';
|
||||
if ($czyscHtmlIExit) exit;
|
||||
}
|
||||
function vvv($var, & $result = null, $is_view = true)
|
||||
{
|
||||
if (is_array($var) || is_object($var)) foreach ($var as $key=> $value) vvv($value, $result[$key], false);
|
||||
else $result = $var;
|
||||
|
||||
if ($is_view) v($result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getSetup($key = null) {
|
||||
$arr = parse_ini_file('setup.ini');
|
||||
return isset($key) ? $arr[$key] : $arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//$_POST['text'] = 'abc';
|
||||
session_start();
|
||||
if (!isset($_SESSION['name'])) return;
|
||||
$text = isset($_POST['text']) ? $_POST['text'] : '';
|
||||
if ($text === '') return;
|
||||
|
||||
$isApc = extension_loaded('apc');
|
||||
|
||||
$setup = getSetup();
|
||||
$time = time();
|
||||
$date = date('Y-m-d', $time);
|
||||
$uniqid = uniqid();
|
||||
$id = $time.'-'.$uniqid;
|
||||
|
||||
$tmpDir = './tmp/';
|
||||
$historyDir = './history/';
|
||||
|
||||
$tmpFile = $tmpDir.'cache';
|
||||
$historyFile = $historyDir.$date;
|
||||
|
||||
$fh = @fopen($historyFile, 'a');
|
||||
if ($fh === false) {
|
||||
mkdir($historyDir);
|
||||
if (!is_dir($tmpDir)) mkdir($tmpDir);
|
||||
$fh = @fopen($historyFile, 'a');
|
||||
}
|
||||
|
||||
/* start semafore */
|
||||
flock($fh, LOCK_EX);
|
||||
|
||||
// data
|
||||
$data = array($id, $_SESSION['name'], stripslashes(htmlspecialchars($text)));
|
||||
|
||||
// write history
|
||||
fwrite($fh, implode('&', $data)."\n");
|
||||
|
||||
// cache
|
||||
if ($isApc) {
|
||||
$cache = apc_fetch('chat');
|
||||
if ($cache === false) {
|
||||
$cache = array();
|
||||
}
|
||||
} else {
|
||||
$cache = @file_get_contents($tmpFile);
|
||||
if ($cache === false) {
|
||||
$cache = array();
|
||||
} else {
|
||||
$cache = unserialize($cache);
|
||||
}
|
||||
}
|
||||
|
||||
array_unshift($cache, $data);
|
||||
|
||||
// delete expired cache
|
||||
$expireTime = floor($time - $setup['interval']/1000 - $setup['expire_cache']);
|
||||
foreach (array_reverse($cache,true) as $k => $e) {
|
||||
if ($e[0] < $expireTime) {
|
||||
unset($cache[$k]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isApc) {
|
||||
apc_store('chat', $cache);
|
||||
} else {
|
||||
file_put_contents($tmpFile, serialize($cache));
|
||||
}
|
||||
|
||||
/* end semafore */
|
||||
flock($fh, LOCK_UN);
|
||||
fclose($fh);
|
77
sources/server.php
Normal file
77
sources/server.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
function v($v, $czyscHtmlIExit = false) {
|
||||
if ($czyscHtmlIExit) ob_end_clean();
|
||||
echo '<pre>' . print_r($v, true) . '</pre>';
|
||||
if ($czyscHtmlIExit) exit;
|
||||
}
|
||||
function vv($v, $czyscHtmlIExit = false) {
|
||||
if ($czyscHtmlIExit) ob_end_clean();
|
||||
echo '<pre>';
|
||||
var_dump($v);
|
||||
echo '</pre>';
|
||||
if ($czyscHtmlIExit) exit;
|
||||
}
|
||||
function vvv($var, & $result = null, $is_view = true)
|
||||
{
|
||||
if (is_array($var) || is_object($var)) foreach ($var as $key=> $value) vvv($value, $result[$key], false);
|
||||
else $result = $var;
|
||||
|
||||
if ($is_view) v($result);
|
||||
}
|
||||
|
||||
//$_POST['id'] = '1305177620-53c14f147c456';
|
||||
if (!isset($_POST['id'])) return;
|
||||
$isApc = extension_loaded('apc');
|
||||
$id = $_POST['id'];
|
||||
$cache = $isApc ? apc_fetch('chat') : @unserialize(file_get_contents('./tmp/cache'));
|
||||
$data = array();
|
||||
if ($id === 'undefined') {
|
||||
$id = empty($cache) ? 0 : $cache[0][0];
|
||||
// first refresh : loads 50 last msg from history
|
||||
$file = './history/'.date('Y-m-d');
|
||||
if (file_exists($file)) {
|
||||
$history = file($file, FILE_IGNORE_NEW_LINES);
|
||||
$history = array_reverse($history);
|
||||
foreach ($history as & $ref) {
|
||||
$ref = explode('&', $ref);
|
||||
}
|
||||
$data = array_slice($history, 0, 50);
|
||||
}
|
||||
} elseif ($id === '0') {
|
||||
if (!empty($cache)) {
|
||||
$id = $cache[0][0];
|
||||
$data = $cache;
|
||||
}
|
||||
} else {
|
||||
$end = end($cache);
|
||||
// read data from cache
|
||||
if ($id >= $end[0]) {
|
||||
foreach ($cache as $k => $c) {
|
||||
if ($c[0] === $id) break;
|
||||
}
|
||||
$data = array_slice($cache, 0, $k);
|
||||
}
|
||||
// read data from history (any problem witch Internet and are delays)
|
||||
else {
|
||||
$date = date('Y-m-d');
|
||||
$history = array();
|
||||
while (($history = array_merge(file('./history/'.$date, FILE_IGNORE_NEW_LINES), $history)) && $history[0] > $id) {
|
||||
$date = date('Y-m-d', strtotime('-1 day', strtotime($date)));
|
||||
if (!file_exists('./history/'.$date)) break;
|
||||
}
|
||||
// prepare history
|
||||
$history = array_reverse($history);
|
||||
foreach ($history as & $ref) {
|
||||
$ref = explode('&', $ref);
|
||||
}
|
||||
// get data
|
||||
foreach ($history as $k => $h) {
|
||||
if ($h[0] === $id) break;
|
||||
}
|
||||
$data = array_slice($history, 0, $k);
|
||||
}
|
||||
$id = $cache[0][0];
|
||||
}
|
||||
|
||||
echo json_encode(array('id' => $id, 'data' => $data));
|
9
sources/setup.ini
Normal file
9
sources/setup.ini
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
; how often get data from serwer
|
||||
interval = 2500 ; in milliseconds
|
||||
|
||||
; extra time for cache when is problem with Internet
|
||||
expire_cache = 60 ; in seconds
|
||||
|
||||
; time for history
|
||||
expire_history = 1 ; in days
|
71
sources/style.css
Normal file
71
sources/style.css
Normal file
|
@ -0,0 +1,71 @@
|
|||
|
||||
/* CSS Document */
|
||||
html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
font: 100% arial;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
p, span {
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
form {
|
||||
margin: 10px 50px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
background: #FEFFF4;
|
||||
font: 110% arial; }
|
||||
|
||||
input[type=submit] {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0000FF;
|
||||
text-decoration: none; }
|
||||
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
#wrapper, #loginform {
|
||||
background: #d8d8d8;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#loginform { padding-top: 18px; width: 50%; height: auto; padding-top: 1.5em; padding-bottom: 2.5em; }
|
||||
|
||||
#loginform p { margin: 5px; }
|
||||
|
||||
#chatbox {
|
||||
text-align: left;
|
||||
margin: 0 50px;
|
||||
padding: 0.5em 1ex 0.1em;
|
||||
background: #FEFFF4;
|
||||
height: calc(100% - 120px);
|
||||
border: 1px solid #C7C7C7;
|
||||
overflow: auto; }
|
||||
|
||||
#usermsg {
|
||||
width: calc(100% - 100px);
|
||||
padding: 0.5ex;
|
||||
border: 1px solid #C7C7C7; }
|
||||
|
||||
#submit { width: 60px; }
|
||||
|
||||
.error { color: #ff0000; }
|
||||
|
||||
#menu { padding: 12.5px 25px 12.5px 25px; }
|
||||
|
||||
.welcome { float: left; }
|
||||
|
||||
.logout { float: right; }
|
||||
|
||||
.msgln { margin:0 0 2px 0; }
|
Loading…
Reference in a new issue