1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/movim_ynh.git synced 2024-09-03 19:46:19 +02:00

update to movim upstream

This commit is contained in:
src386 2016-02-25 11:28:01 +01:00
parent e168f36e39
commit c06392fa2a
35 changed files with 367 additions and 138 deletions

View file

@ -1,7 +1,7 @@
**Changelog** **Changelog**
1.7 2016-? 1.7 2016-?
- Update to movim 0.9 git2016-02-19 - Update to movim 0.9 git2016-02-25
1.6.1 2016-02-12 1.6.1 2016-02-12
- Update to movim 0.9 git2016-01-27 - Update to movim 0.9 git2016-01-27

View file

@ -5,7 +5,7 @@ Movim is a decentralized social network, written in PHP and HTML5 and based on t
It is recommended to use a "valid" certificate to use Movim, auto-signed is sometimes problematic. You might want to take a look a StartSSL or Let's Encrypt. It is recommended to use a "valid" certificate to use Movim, auto-signed is sometimes problematic. You might want to take a look a StartSSL or Let's Encrypt.
Provided Movim version : 0.9 git2016-02-19 Provided Movim version : 0.9 git2016-02-25
Please read CHANGELOG. Please read CHANGELOG.

View file

@ -223,6 +223,17 @@ function cleanJid($jid)
return reset($explode); return reset($explode);
} }
/*
* Extract the CID
*/
function getCid($string)
{
preg_match("/(\w+)\@/", $string, $matches);
if(is_array($matches)) {
return $matches[1];
}
}
/* /*
* Explode JID * Explode JID
*/ */

View file

@ -12,13 +12,13 @@ class Cache extends Model{
$this->_struct = ' $this->_struct = '
{ {
"session" : "session" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"name" : "name" :
{"type":"string", "size":32, "mandatory":true, "key":true }, {"type":"string", "size":32, "key":true },
"data" : "data" :
{"type":"text", "mandatory":true }, {"type":"text", "mandatory":true },
"timestamp" : "timestamp" :
{"type":"date" } {"type":"date", "mandatory":true }
}'; }';
parent::__construct(); parent::__construct();

View file

@ -13,11 +13,11 @@ class Caps extends Model {
$this->_struct = ' $this->_struct = '
{ {
"node" : "node" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":128, "key":true },
"category" : "category" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":16, "mandatory":true },
"type" : "type" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":16, "mandatory":true },
"name" : "name" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":128, "mandatory":true },
"features" : "features" :

View file

@ -16,9 +16,9 @@ class Conference extends Model {
$this->_struct = ' $this->_struct = '
{ {
"jid" : "jid" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":128, "key":true },
"conference" : "conference" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":128, "key":true },
"name" : "name" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":128, "mandatory":true },
"nick" : "nick" :

View file

@ -75,11 +75,11 @@ class Contact extends Model {
$this->_struct = ' $this->_struct = '
{ {
"jid" : "jid" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"fn" : "fn" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"name" : "name" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"date" : "date" :
{"type":"date", "size":11 }, {"type":"date", "size":11 },
"url" : "url" :
@ -89,21 +89,21 @@ class Contact extends Model {
"adrlocality" : "adrlocality" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"adrpostalcode" : "adrpostalcode" :
{"type":"string", "size":128 }, {"type":"string", "size":12 },
"adrcountry" : "adrcountry" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"gender" : "gender" :
{"type":"string", "size":1 }, {"type":"string", "size":1 },
"marital" : "marital" :
{"type":"string", "size":20 }, {"type":"string", "size":16 },
"description" : "description" :
{"type":"text"}, {"type":"text"},
"mood" : "mood" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"activity" : "activity" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"nickname" : "nickname" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"tuneartist" : "tuneartist" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"tunelenght" : "tunelenght" :
@ -117,25 +117,25 @@ class Contact extends Model {
"tunetrack" : "tunetrack" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"loclatitude" : "loclatitude" :
{"type":"string", "size":128 }, {"type":"string", "size":32 },
"loclongitude" : "loclongitude" :
{"type":"string", "size":128 }, {"type":"string", "size":32 },
"localtitude" : "localtitude" :
{"type":"int", "size":11 }, {"type":"int", "size":11 },
"loccountry" : "loccountry" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"loccountrycode" : "loccountrycode" :
{"type":"string", "size":128 }, {"type":"string", "size":2 },
"locregion" : "locregion" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"locpostalcode" : "locpostalcode" :
{"type":"string", "size":128 }, {"type":"string", "size":32 },
"loclocality" : "loclocality" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"locstreet" : "locstreet" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"locbuilding" : "locbuilding" :
{"type":"string", "size":128 }, {"type":"string", "size":32 },
"loctext" : "loctext" :
{"type":"text" }, {"type":"text" },
"locuri" : "locuri" :
@ -151,9 +151,9 @@ class Contact extends Model {
"avatarhash" : "avatarhash" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"created" : "created" :
{"type":"date" }, {"type":"date", "mandatory":true },
"updated" : "updated" :
{"type":"date" } {"type":"date", "mandatory":true }
}'; }';
parent::__construct(); parent::__construct();

View file

@ -19,13 +19,13 @@ class Item extends Model {
$this->_struct = ' $this->_struct = '
{ {
"server" : "server" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"jid" : "jid" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"node" : "node" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":96, "key":true },
"creator" : "creator" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"name" : "name" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"created" : "created" :
@ -33,7 +33,7 @@ class Item extends Model {
"description" : "description" :
{"type":"text" }, {"type":"text" },
"updated" : "updated" :
{"type":"date"} {"type":"date", "mandatory":true}
}'; }';
parent::__construct(); parent::__construct();

View file

@ -26,22 +26,24 @@ class Message extends Model {
public $publishedPrepared; // Only for chat purpose public $publishedPrepared; // Only for chat purpose
public $edited; public $edited;
public $sticker; // The sticker code
public function __construct() public function __construct()
{ {
$this->_struct = ' $this->_struct = '
{ {
"session" : "session" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":96, "mandatory":true },
"id" : "id" :
{"type":"string", "size":36}, {"type":"string", "size":64},
"jidto" : "jidto" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":96, "mandatory":true },
"jidfrom" : "jidfrom" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":96, "mandatory":true },
"resource" : "resource" :
{"type":"string", "size":128 }, {"type":"string", "size":128, "mandatory":true },
"type" : "type" :
{"type":"string", "size":20 }, {"type":"string", "size":16, "mandatory":true },
"subject" : "subject" :
{"type":"text"}, {"type":"text"},
"thread" : "thread" :
@ -51,11 +53,13 @@ class Message extends Model {
"html" : "html" :
{"type":"text"}, {"type":"text"},
"published" : "published" :
{"type":"date"}, {"type":"date", "mandatory":true},
"delivered" : "delivered" :
{"type":"date"}, {"type":"date"},
"edited" : "edited" :
{"type":"int", "size":1} {"type":"int", "size":1},
"sticker" :
{"type":"string", "size":128 }
}'; }';
parent::__construct(); parent::__construct();
@ -86,11 +90,23 @@ class Message extends Model {
$this->type = (string)$stanza->attributes()->type; $this->type = (string)$stanza->attributes()->type;
} }
$this->__set('body', (string)$stanza->body); if($stanza->body)
$this->__set('subject', (string)$stanza->subject); $this->__set('body', (string)$stanza->body);
if($stanza->subject)
$this->__set('subject', (string)$stanza->subject);
$images = (bool)($this->type == 'chat'); $images = (bool)($this->type == 'chat');
if($stanza->html) {
$xhtml = new \SimpleXMLElement('<body xmlns="http://www.w3.org/1999/xhtml">'.(string)$stanza->html->body.'</body>');
$xhtml->registerXPathNamespace('xhtml', 'http://www.w3.org/1999/xhtml');
$img = $xhtml->xpath('//xhtml:img/@src')[0];
if($img) {
$this->sticker = getCid((string)$img);
}
}
/*if($stanza->html) { /*if($stanza->html) {
$this->html = \cleanHTMLTags($stanza->html->body->asXML()); $this->html = \cleanHTMLTags($stanza->html->body->asXML());
$this->html = \fixSelfClosing($this->html); $this->html = \fixSelfClosing($this->html);

View file

@ -50,7 +50,8 @@ class MessageDAO extends SQL {
body, body,
html, html,
published, published,
delivered) delivered,
sticker)
values( values(
:id, :id,
:session, :session,
@ -63,7 +64,8 @@ class MessageDAO extends SQL {
:body, :body,
:html, :html,
:published, :published,
:delivered :delivered,
:sticker
)'; )';
$this->prepare( $this->prepare(
@ -80,7 +82,8 @@ class MessageDAO extends SQL {
'body' => $message->body, 'body' => $message->body,
'html' => $message->html, 'html' => $message->html,
'published' => $message->published, 'published' => $message->published,
'delivered' => $message->delivered 'delivered' => $message->delivered,
'sticker' => $message->sticker
) )
); );
} }

View file

@ -43,15 +43,15 @@ class Postn extends Model {
$this->_struct = ' $this->_struct = '
{ {
"origin" : "origin" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"node" : "node" :
{"type":"string", "size":96, "mandatory":true, "key":true }, {"type":"string", "size":96, "key":true },
"nodeid" : "nodeid" :
{"type":"string", "size":96, "mandatory":true, "key":true }, {"type":"string", "size":96, "key":true },
"aname" : "aname" :
{"type":"string", "size":128 }, {"type":"string", "size":128 },
"aid" : "aid" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"aemail" : "aemail" :
{"type":"string", "size":64 }, {"type":"string", "size":64 },
"title" : "title" :
@ -73,16 +73,16 @@ class Postn extends Model {
{"type":"date" }, {"type":"date" },
"lat" : "lat" :
{"type":"string", "size":128 }, {"type":"string", "size":32 },
"lon" : "lon" :
{"type":"string", "size":128 }, {"type":"string", "size":32 },
"links" : "links" :
{"type":"text" }, {"type":"text" },
"picture" : "picture" :
{"type":"int", "size":4 }, {"type":"int", "size":4 },
"hash" : "hash" :
{"type":"string", "size":128 } {"type":"string", "size":128, "mandatory":true }
}'; }';
parent::__construct(); parent::__construct();

View file

@ -38,11 +38,11 @@ class Presence extends Model {
$this->_struct = ' $this->_struct = '
{ {
"id" : "id" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":64, "mandatory":true },
"session" : "session" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"jid" : "jid" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"resource" : "resource" :
{"type":"string", "size":64, "key":true }, {"type":"string", "size":64, "key":true },
"value" : "value" :

View file

@ -10,8 +10,6 @@ class RosterLink extends Model {
public $rosterask; public $rosterask;
public $rostersubscription; public $rostersubscription;
protected $realname;
protected $groupname; protected $groupname;
public $chaton; public $chaton;
@ -22,19 +20,17 @@ class RosterLink extends Model {
$this->_struct = ' $this->_struct = '
{ {
"session" : "session" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"jid" : "jid" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":96, "key":true },
"rostername" : "rostername" :
{"type":"string", "size":128 }, {"type":"string", "size":96 },
"rosterask" : "rosterask" :
{"type":"string", "size":128 }, {"type":"string", "size":16 },
"rostersubscription" : "rostersubscription" :
{"type":"string", "size":128 }, {"type":"string", "size":4, "mandatory":true },
"realname" :
{"type":"string", "size":128 },
"groupname" : "groupname" :
{"type":"string", "size":128 }, {"type":"string", "size":64 },
"chaton" : "chaton" :
{"type":"int", "size":11 } {"type":"int", "size":11 }
}'; }';

View file

@ -12,7 +12,6 @@ class RosterLinkDAO extends SQL {
rostername, rostername,
rosterask, rosterask,
rostersubscription, rostersubscription,
realname,
groupname, groupname,
chaton) chaton)
values ( values (
@ -21,7 +20,6 @@ class RosterLinkDAO extends SQL {
:rostername, :rostername,
:rosterask, :rosterask,
:rostersubscription, :rostersubscription,
:realname,
:groupname, :groupname,
:chaton :chaton
)'; )';
@ -34,7 +32,6 @@ class RosterLinkDAO extends SQL {
'rostername' => $r->rostername, 'rostername' => $r->rostername,
'rosterask' => $r->rosterask, 'rosterask' => $r->rosterask,
'rostersubscription' => $r->rostersubscription, 'rostersubscription' => $r->rostersubscription,
'realname' => $r->realname,
'groupname' => $r->groupname, 'groupname' => $r->groupname,
'chaton' => $r->chaton 'chaton' => $r->chaton
) )
@ -52,7 +49,6 @@ class RosterLinkDAO extends SQL {
rostername, rostername,
rosterask, rosterask,
rostersubscription, rostersubscription,
realname,
groupname, groupname,
chaton) chaton)
values values
@ -69,7 +65,6 @@ class RosterLinkDAO extends SQL {
:rostername_$i, :rostername_$i,
:rosterask_$i, :rosterask_$i,
:rostersubscription_$i, :rostersubscription_$i,
:realname_$i,
:groupname_$i, :groupname_$i,
:chaton_$i :chaton_$i
),"; ),";
@ -82,7 +77,6 @@ class RosterLinkDAO extends SQL {
"rostername_$i" => $r->rostername, "rostername_$i" => $r->rostername,
"rosterask_$i" => $r->rosterask, "rosterask_$i" => $r->rosterask,
"rostersubscription_$i" => $r->rostersubscription, "rostersubscription_$i" => $r->rostersubscription,
"realname_$i" => $r->realname,
"groupname_$i" => $r->groupname, "groupname_$i" => $r->groupname,
"chaton_$i" => $r->chaton "chaton_$i" => $r->chaton
) )
@ -107,7 +101,6 @@ class RosterLinkDAO extends SQL {
set rostername = :rostername, set rostername = :rostername,
rosterask = :rosterask, rosterask = :rosterask,
rostersubscription = :rostersubscription, rostersubscription = :rostersubscription,
realname = :realname,
groupname = :groupname, groupname = :groupname,
chaton = :chaton chaton = :chaton
where session = :session where session = :session
@ -121,7 +114,6 @@ class RosterLinkDAO extends SQL {
'rostername' => $r->rostername, 'rostername' => $r->rostername,
'rosterask' => $r->rosterask, 'rosterask' => $r->rosterask,
'rostersubscription' => $r->rostersubscription, 'rostersubscription' => $r->rostersubscription,
'realname' => $r->realname,
'groupname' => $r->groupname, 'groupname' => $r->groupname,
'chaton' => $r->chaton 'chaton' => $r->chaton
) )

View file

@ -24,15 +24,15 @@ class Sessionx extends Model {
$this->_struct = ' $this->_struct = '
{ {
"session" : "session" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":32, "key":true },
"username" : "username" :
{"type":"string", "size":64 }, {"type":"string", "size":64 },
"password" : "password" :
{"type":"string", "size":64 }, {"type":"string", "size":64 },
"hash" : "hash" :
{"type":"string", "size":128 },
"resource" :
{"type":"string", "size":64 }, {"type":"string", "size":64 },
"resource" :
{"type":"string", "size":16 },
"rid" : "rid" :
{"type":"int", "size":8, "mandatory":true }, {"type":"int", "size":8, "mandatory":true },
"sid" : "sid" :
@ -54,7 +54,7 @@ class Sessionx extends Model {
"timestamp" : "timestamp" :
{"type":"date" }, {"type":"date" },
"mechanism" : "mechanism" :
{"type":"string", "size":64 } {"type":"string", "size":16 }
}'; }';
parent::__construct(); parent::__construct();

View file

@ -19,11 +19,11 @@ class Subscription extends Model {
$this->_struct = ' $this->_struct = '
{ {
"jid" : "jid" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"server" : "server" :
{"type":"string", "size":64, "mandatory":true, "key":true }, {"type":"string", "size":64, "key":true },
"node" : "node" :
{"type":"string", "size":128, "mandatory":true, "key":true }, {"type":"string", "size":128, "key":true },
"subscription" : "subscription" :
{"type":"string", "size":128, "mandatory":true }, {"type":"string", "size":128, "mandatory":true },
"subid" : "subid" :

View file

@ -1,3 +1,4 @@
<?php $this->widget('Stickers');?>
<nav class="color dark"> <nav class="color dark">
<?php $this->widget('Presence');?> <?php $this->widget('Presence');?>
<?php $this->widget('Navigation');?> <?php $this->widget('Navigation');?>

View file

@ -8,6 +8,8 @@ use Moxl\Xec\Action\Muc\GetConfig;
use Moxl\Xec\Action\Muc\SetConfig; use Moxl\Xec\Action\Muc\SetConfig;
use Moxl\Xec\Action\Muc\SetSubject; use Moxl\Xec\Action\Muc\SetSubject;
use Moxl\Xec\Action\BOB\Request;
use Respect\Validation\Validator; use Respect\Validation\Validator;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
@ -28,8 +30,11 @@ class Chat extends WidgetBase
$this->registerEvent('paused', 'onPaused'); $this->registerEvent('paused', 'onPaused');
$this->registerEvent('gone', 'onGone'); $this->registerEvent('gone', 'onGone');
$this->registerEvent('subject', 'onConferenceSubject'); $this->registerEvent('subject', 'onConferenceSubject');
$this->registerEvent('muc_getconfig_handle', 'onRoomConfig'); $this->registerEvent('muc_getconfig_handle', 'onRoomConfig');
$this->registerEvent('muc_setconfig_handle', 'onRoomConfigSaved'); $this->registerEvent('muc_setconfig_handle', 'onRoomConfigSaved');
$this->registerEvent('bob_request_handle', 'onSticker');
//$this->registerEvent('muc_setsubject_handle', 'onRoomSubjectChanged'); //$this->registerEvent('muc_setsubject_handle', 'onRoomSubjectChanged');
//$this->registerEvent('presence', 'onPresence'); //$this->registerEvent('presence', 'onPresence');
} }
@ -96,9 +101,16 @@ class Chat extends WidgetBase
if(!preg_match('#^\?OTR#', $message->body)) { if(!preg_match('#^\?OTR#', $message->body)) {
RPC::call('Chat.appendMessage', $this->prepareMessage($message)); RPC::call('Chat.appendMessage', $this->prepareMessage($message));
RPC::call('Chat.cleanBubbles');
} }
} }
function onSticker($packet)
{
list($to, $cid) = array_values($packet->content);
$this->ajaxGet($to);
}
function onComposing($array) function onComposing($array)
{ {
$this->setState($array, $this->__('message.composing')); $this->setState($array, $this->__('message.composing'));
@ -375,12 +387,13 @@ class Chat extends WidgetBase
if(count($messages) > 0) { if(count($messages) > 0) {
Notification::append(false, $this->__('message.history', count($messages))); Notification::append(false, $this->__('message.history', count($messages)));
}
foreach($messages as $message) { foreach($messages as $message) {
if(!preg_match('#^\?OTR#', $message->body)) { if(!preg_match('#^\?OTR#', $message->body)) {
RPC::call('Chat.appendMessage', $this->prepareMessage($message), true); RPC::call('Chat.appendMessage', $this->prepareMessage($message), true);
}
} }
RPC::call('Chat.cleanBubbles');
} }
} }
@ -572,6 +585,21 @@ class Chat extends WidgetBase
// $message->body = prepareString(htmlentities($message->body , ENT_COMPAT,'UTF-8')); // $message->body = prepareString(htmlentities($message->body , ENT_COMPAT,'UTF-8'));
} }
if(isset($message->sticker)) {
$p = new Picture;
$sticker = $p->get($message->sticker, false, false, 'png');
if($sticker == false) {
$r = new Request;
$r->setTo($message->jidfrom)
->setResource($message->resource)
->setCid($message->sticker)
->request();
} else {
$message->sticker = $sticker;
}
}
if($message->type == 'groupchat') { if($message->type == 'groupchat') {
$message->color = stringToColor($message->session.$message->resource.$message->jidfrom.$message->type); $message->color = stringToColor($message->session.$message->resource.$message->jidfrom.$message->type);
} }

View file

@ -77,6 +77,11 @@
</table> </table>
</section> </section>
<div> <div>
<!--
<a onclick="Stickers_ajaxShow()" class="button flat">
Stickers
</a>
-->
<a onclick="Dialog.clear()" class="button flat"> <a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')} {$c->__('button.close')}
</a> </a>

View file

@ -2,7 +2,6 @@ var Chat = {
left : null, left : null,
right: null, right: null,
room: null, room: null,
previous: null,
date: null, date: null,
lastScroll: null, lastScroll: null,
edit: false, edit: false,
@ -84,6 +83,7 @@ var Chat = {
Chat.appendMessage(messages[i], false); Chat.appendMessage(messages[i], false);
} }
Chat.edit = false; Chat.edit = false;
Chat.cleanBubbles();
} }
}, },
appendMessage : function(message, prepend) { appendMessage : function(message, prepend) {
@ -120,24 +120,12 @@ var Chat = {
if(conversation) { if(conversation) {
conversation.appendChild(bubble); conversation.appendChild(bubble);
} }
//bubble.querySelector('p.message').className = '';
} else if(Chat.left != null) { } else if(Chat.left != null) {
if(message.session == message.jidfrom) { if(message.session == message.jidfrom) {
bubble = Chat.right.cloneNode(true); bubble = Chat.right.cloneNode(true);
if(Chat.previous == 'right') {
bubble.className += ' same';
}
Chat.previous = 'right';
id = message.jidto + '_conversation'; id = message.jidto + '_conversation';
} else { } else {
bubble = Chat.left.cloneNode(true); bubble = Chat.left.cloneNode(true);
if(Chat.previous == 'left') {
bubble.className += ' same';
}
Chat.previous = 'left';
id = message.jidfrom + '_conversation'; id = message.jidfrom + '_conversation';
} }
@ -152,8 +140,16 @@ var Chat = {
message.body = message.body.substr(4); message.body = message.body.substr(4);
} }
if(message.sticker != null) {
bubble.querySelector('div.bubble').className += ' sticker';
}
if(bubble) { if(bubble) {
bubble.querySelector('div.bubble > p').innerHTML = message.body.replace(/\r\n?|\n/g, '<br />'); if(message.sticker != null) {
bubble.querySelector('div.bubble > p').innerHTML = '<img src="' + message.sticker + '"/>';
} else {
bubble.querySelector('div.bubble > p').innerHTML = message.body.replace(/\r\n?|\n/g, '<br />');
}
var info = bubble.querySelector('div.bubble > span.info'); var info = bubble.querySelector('div.bubble > span.info');
info.innerHTML = message.publishedPrepared; info.innerHTML = message.publishedPrepared;
@ -177,6 +173,8 @@ var Chat = {
var elem = document.getElementById(message.id); var elem = document.getElementById(message.id);
if(elem) if(elem)
elem.parentElement.replaceChild(bubble, elem); elem.parentElement.replaceChild(bubble, elem);
else
movim_append(id, bubble.outerHTML);
} else { } else {
movim_append(id, bubble.outerHTML); movim_append(id, bubble.outerHTML);
} }
@ -189,6 +187,28 @@ var Chat = {
} }
if(scrolled && prepend == null) MovimTpl.scrollPanel(); if(scrolled && prepend == null) MovimTpl.scrollPanel();
},
cleanBubbles : function() {
var bubbles = document.querySelectorAll('#chat_widget .contained ul.list > li');
var previous = null;
for(var i = 0, len = bubbles.length; i < len; ++i ) {
bubbles[i].className = bubbles[i].className.replace(' same', '');
if(bubbles[i].className.indexOf('oppose') > -1) {
if(previous == 'right') {
bubbles[i].className += ' same';
}
previous = 'right';
} else {
if(previous == 'left') {
bubbles[i].className += ' same';
}
previous = 'left';
}
}
} }
} }

View file

@ -49,7 +49,7 @@ var Login = {
} }
var s = localStorage.getObject('previousSessions'); var s = localStorage.getObject('previousSessions');
if(s.indexOf(jid) == -1) { if(s.indexOf(jid) == -1 && jid != '') {
s.push(jid); s.push(jid);
localStorage.setObject('previousSessions', s); localStorage.setObject('previousSessions', s);
} }

View file

@ -0,0 +1,127 @@
<?php
use Moxl\Xec\Action\Message\Publish;
use Moxl\Xec\Action\BOB\Answer;
use Ramsey\Uuid\Uuid;
use Respect\Validation\Validator;
class Stickers extends WidgetBase
{
function load()
{
$this->registerEvent('bob', 'onRequest');
}
function onRequest($packet)
{
$content = $packet->content;
$to = $content[0];
$id = $content[1];
$cid = $content[2];
list($c, $ext) = explode('@', $cid);
list($sh, $key) = explode('+', $c);
$base64 = base64_encode(file_get_contents(dirname(__FILE__).'/stickers/'.$key.'.png'));
$a = new Answer;
$a->setTo($to)
->setId($id)
->setCid($cid)
->setType('image/png')
->setBase64($base64)
->request();
}
function ajaxSend($to, $file)
{
if(!$this->validateJid($to)) return;
list($key, $ext) = explode('.', $file);
$filepath = dirname(__FILE__).'/stickers/'.$key.'.png';
if(!file_exists($filepath)) return;
// We get the base64
$base64 = base64_encode(file_get_contents($filepath));
// Caching the picture
$p = new Picture;
$p->fromBase($base64);
$p->set($key, 'png');
// Creating a message
$m = new \Modl\Message();
$m->session = $this->user->getLogin();
$m->jidto = echapJid($to);
$m->jidfrom = $this->user->getLogin();
$m->sticker = $key;
$m->body = 'A Stickers has been sent using Movim';
$m->published = gmdate('Y-m-d H:i:s');
$m->delivered = gmdate('Y-m-d H:i:s');
$session = \Sessionx::start();
$m->id = Uuid::uuid4();
$m->type = 'chat';
$m->resource = $session->resource;
// Sending the sticker
$html = "<p><img alt='Sticker' src='cid:sha1+".$key."@bob.xmpp.org'/></p>";
$p = new Publish;
$p->setTo($m->jidto)
->setContent($m->body)
->setHTML($html)
->setId($m->id)
->request();
$md = new \Modl\MessageDAO();
$md->set($m);
// Sending it to Chat
$packet = new Moxl\Xec\Payload\Packet;
$packet->content = $m;
$c = new Chat;
$c->onMessage($packet/*, true*/);
}
function ajaxShow($to)
{
if(!$this->validateJid($to)) return;
$files = scandir(dirname(__FILE__).'/stickers/');
array_shift($files);
array_shift($files);
$view = $this->tpl();
$view->assign('jid', $to);
$view->assign('stickers', $files);
$view->assign('path', $this->respath('stickers').'/');
Dialog::fill($view->draw('_stickers', true), true);
}
/**
* @brief Validate the jid
*
* @param string $jid
*/
private function validateJid($jid)
{
$validate_jid = Validator::stringType()->noWhitespace()->length(6, 60);
if(!$validate_jid->validate($jid)) return false;
else return true;
}
function display()
{
}
}

View file

@ -0,0 +1,17 @@
<section class="scroll">
<ul class="list flex active">
{loop="$stickers"}
<li class="block" onclick="Stickers_ajaxSend('{$jid}', '{$value}'); Dialog.clear();">
<img src="{$path}{$value}"/>
</li>
{/loop}
</ul>
</section>
<div>
<a onclick="Chat_ajaxSmiley()" class="button flat">
Emojis
</a>
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View file

@ -344,7 +344,7 @@ class Bootstrap {
return["Account","AccountNext","Ack","AdHoc","Avatar","Bookmark","Chat", return["Account","AccountNext","Ack","AdHoc","Avatar","Bookmark","Chat",
"Chats","Config","Contact","Dialog","Group","Groups","Header","Init", "Chats","Config","Contact","Dialog","Group","Groups","Header","Init",
"Login","LoginAnonymous","Menu","Notifs","Post","Presence","Publish", "Login","LoginAnonymous","Menu","Notifs","Post","Presence","Publish",
"Rooms","Roster","Upload","Vcard4"]; "Rooms","Roster","Stickers","Upload","Vcard4"];
} }
} }

View file

@ -99,7 +99,7 @@ $stdin_behaviour = function ($data) use (&$conn, $loop, &$buffer, &$connector, &
if(!empty($xml) && $conn) { if(!empty($xml) && $conn) {
//$timestamp = time(); //$timestamp = time();
$conn->write(trim($xml)); $conn->write(trim($xml));
#fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
} }
} }
} else { } else {
@ -148,7 +148,7 @@ $xmpp_behaviour = function (React\Stream\Stream $stream) use (&$conn, $loop, &$s
$restart = true; $restart = true;
} }
#fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n"); fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n");
#fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets : ".\sizeToCleanSize(memory_get_usage())."\n"); #fwrite(STDERR, colorize(getenv('sid'), 'yellow')." widgets : ".\sizeToCleanSize(memory_get_usage())."\n");
\Moxl\API::clear(); \Moxl\API::clear();
@ -182,7 +182,7 @@ $xmpp_behaviour = function (React\Stream\Stream $stream) use (&$conn, $loop, &$s
if(!empty($xml)) { if(!empty($xml)) {
//$timestamp = time(); //$timestamp = time();
$conn->write(trim($xml)); $conn->write(trim($xml));
#fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n"); fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
} }
\Moxl\API::clear(); \Moxl\API::clear();

View file

@ -5,6 +5,7 @@ class Picture {
private $_uri = CACHE_URI; private $_uri = CACHE_URI;
private $_key; private $_key;
private $_bin = false; private $_bin = false;
private $_formats = ['jpeg' => '.jpg', 'png' => '.png'];
/** /**
* @desc Load a bin picture from a path * @desc Load a bin picture from a path
@ -41,30 +42,31 @@ class Picture {
* @param $height The height requested * @param $height The height requested
* @return The url of the picture * @return The url of the picture
*/ */
public function get($key, $width = false, $height = false) { public function get($key, $width = false, $height = false, $format = 'jpeg') {
if(!in_array($format, array_keys($this->_formats))) $format = 'jpeg';
$this->_key = $key; $this->_key = $key;
$original = $this->_path.md5($this->_key).'.jpg'; $original = $this->_path.md5($this->_key).$this->_formats[$format];
// We request the original picture // We request the original picture
if($width == false) { if($width == false) {
if(file_exists($original)) { if(file_exists($original)) {
$this->fromPath($original); $this->fromPath($original);
return $this->_uri.md5($this->_key).'.jpg'; return $this->_uri.md5($this->_key).$this->_formats[$format];
} else { } else {
return false; return false;
} }
// We request a specific size // We request a specific size
} else { } else {
if(file_exists($this->_path.md5($this->_key).'_'.$width.'.jpg')) { if(file_exists($this->_path.md5($this->_key).'_'.$width.$this->_formats[$format])) {
$this->fromPath($this->_path.md5($this->_key).'_'.$width.'.jpg'); $this->fromPath($this->_path.md5($this->_key).'_'.$width.$this->_formats[$format]);
return $this->_uri.md5($this->_key).'_'.$width.'.jpg'; return $this->_uri.md5($this->_key).'_'.$width.$this->_formats[$format];
} else { } else {
if(file_exists($original)) { if(file_exists($original)) {
$this->fromPath($original); $this->fromPath($original);
$this->createThumbnail($width, $height); $this->createThumbnail($width, $height);
return $this->_uri.md5($this->_key).'_'.$width.'.jpg'; return $this->_uri.md5($this->_key).'_'.$width.$this->_formats[$format];
} else { } else {
return false; return false;
} }
@ -76,9 +78,11 @@ class Picture {
* @desc Save a picture (original size) * @desc Save a picture (original size)
* @param $key The key of the picture * @param $key The key of the picture
*/ */
public function set($key) { public function set($key, $format = 'jpeg') {
if(!in_array($format, array_keys($this->_formats))) $format = 'jpeg';
$this->_key = $key; $this->_key = $key;
$path = $this->_path.md5($this->_key).'.jpg'; $path = $this->_path.md5($this->_key).$this->_formats[$format];
// If the file exist we replace it // If the file exist we replace it
if(file_exists($path) && $this->_bin) { if(file_exists($path) && $this->_bin) {
@ -89,7 +93,7 @@ class Picture {
glob( glob(
$this->_path. $this->_path.
md5($key). md5($key).
'*.jpg', '*'.$this->_formats[$format],
GLOB_NOSORT GLOB_NOSORT
) as $path_thumb) { ) as $path_thumb) {
unlink($path_thumb); unlink($path_thumb);
@ -101,6 +105,7 @@ class Picture {
try { try {
$im->readImageBlob($this->_bin); $im->readImageBlob($this->_bin);
if($im != false) { if($im != false) {
$im->setImageFormat($format);
$im->setImageCompressionQuality(95); $im->setImageCompressionQuality(95);
$im->setInterlaceScheme(Imagick::INTERLACE_PLANE); $im->setInterlaceScheme(Imagick::INTERLACE_PLANE);
$im->writeImage($path); $im->writeImage($path);
@ -116,13 +121,15 @@ class Picture {
* @desc Create a thumbnail of the picture and save it * @desc Create a thumbnail of the picture and save it
* @param $size The size requested * @param $size The size requested
*/ */
private function createThumbnail($width, $height = false) { private function createThumbnail($width, $height = false, $format = 'jpeg') {
if(!in_array($format, array_keys($this->_formats))) $format = 'jpeg';
if(!$height) $height = $width; if(!$height) $height = $width;
$path = $this->_path.md5($this->_key).'_'.$width.'.jpg'; $path = $this->_path.md5($this->_key).'_'.$width.$this->_formats[$format];
$im = new Imagick; $im = new Imagick;
$im->readImageBlob($this->_bin); $im->readImageBlob($this->_bin);
$im->setImageFormat($format);
$geo = $im->getImageGeometry(); $geo = $im->getImageGeometry();

View file

@ -281,15 +281,10 @@ ul li span.counter.bottom {
/* Bubble */ /* Bubble */
ul li div.bubble { ul li div.bubble {
padding: 1.25rem 2rem 0.75rem;
border-radius: 0.5rem;
line-height: 2.75rem;
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
display: block; display: block;
font-size: 1.75rem; font-size: 1.75rem;
background-color: white;
border-color: white;
max-width: calc(100% - 11rem); max-width: calc(100% - 11rem);
float: left; float: left;
@ -298,6 +293,14 @@ ul li div.bubble {
width: auto; width: auto;
} }
ul li div.bubble:not(.sticker) {
padding: 1.25rem 2rem 0.75rem;
border-radius: 0.5rem;
line-height: 2.75rem;
background-color: white;
border-color: white;
}
ul li div.bubble > p { ul li div.bubble > p {
overflow: hidden; overflow: hidden;
display: inline-block; display: inline-block;
@ -308,6 +311,9 @@ ul li.oppose div.bubble {
margin-right: 9rem; margin-right: 9rem;
float: right; float: right;
position: initial; position: initial;
}
ul li.oppose div.bubble:not(.sticker) {
background-color: #f5f5f5; background-color: #f5f5f5;
} }
@ -333,7 +339,7 @@ ul li .quote {
font-style: italic; font-style: italic;
} }
ul li:not(.same) div.bubble:before { ul li:not(.same) div.bubble:not(.sticker):before {
content: ""; content: "";
position: absolute; position: absolute;
top: 0; top: 0;
@ -344,7 +350,7 @@ ul li:not(.same) div.bubble:before {
border-right: 1.5rem solid transparent; border-right: 1.5rem solid transparent;
} }
ul li.oppose:not(.same) div.bubble:before { ul li.oppose:not(.same) div.bubble:not(.sticker):before {
left: calc(100% - 10.5rem); left: calc(100% - 10.5rem);
top: 1.5rem; top: 1.5rem;
border-top-color: #f5f5f5; border-top-color: #f5f5f5;