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-05-20 10:51:42 +02:00
parent 661783a93e
commit 5e3ba4dbbf
75 changed files with 1339 additions and 652 deletions

View file

@ -1,5 +1,8 @@
**Changelog**
1.9 2016-*
- Update to movim 0.9 git2016-05-19
1.8 2016-04-15
- Update to movim 0.9 git2016-04-15
- Removed "environment" variable on mud.php (obsolete)

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.
Provided Movim version : 0.9 git2016-04-15
Provided Movim version : 0.9 git2016-05-19
Please read CHANGELOG.

View file

@ -3,6 +3,8 @@ Movim Changelog
v0.9.1 (trunk)
---------------------------
* Fix Pubsub metadata handling for some XMPP servers
* Add silent notifications for chatrooms
* Put your own XMPP server as default in the configuration (movim.eu in fallback)
* Close the Dialog box when pressing ESC
* Moving values from Sessionx to Session

View file

@ -98,6 +98,12 @@ var MovimTpl = {
target.innerHTML = html;
}
},
append : function(selector, html) {
target = document.querySelector(selector);
if(target) {
target.insertAdjacentHTML('beforeend', html);
}
},
isPanel : function() {
if(movim_has_class('main section > div:first-child:nth-last-child(2) ~ div', 'enabled')) {
return true;

View file

@ -47,7 +47,7 @@ class MovimEmoji
function addUrls($string, $preview = false) {
// Add missing links
return preg_replace_callback(
"/([\w\"'>]+\:\/\/[\w-?'&;#+,%:~=\.\/\@]+)/u", function ($match) use($preview) {
"/([\w\"'>]+\:\/\/[\w-?'&;#+,%:~=\.\/\@\(\)]+)/u", function ($match) use($preview) {
if(!in_array(substr($match[0], 0, 1), array('>', '"', '\''))) {
$content = $match[0];
@ -187,21 +187,6 @@ function explodeJid($jid)
);
}
/**
* Return a URIfied string
* @param string
* @return string
*/
function stringToUri($url) {
$url = utf8_decode($url);
$url = strtolower(strtr($url, utf8_decode('ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ()[]\'"~$&%*@ç!?;,:/\^¨€{}<>|+- .'), 'aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn -- c --- e --_'));
$url = str_replace(' ', '', $url);
$url = str_replace('---', '-', $url);
$url = str_replace('--', '-', $url);
$url = trim($url,'-');
return $url;
}
/**
* Return a human readable filesize
* @param string size in bytes

View file

@ -480,6 +480,41 @@ class ContactDAO extends SQL {
return $this->run('RosterContact');
}
function search($key)
{
$this->_sql = '
select
rosterlink.jid,
contact.fn,
contact.name,
contact.nickname,
contact.tuneartist,
contact.tunetitle,
rosterlink.rostername,
rosterlink.rostersubscription,
rosterlink.groupname,
rosterlink.chaton
from rosterlink
left outer join contact
on rosterlink.jid = contact.jid
where rosterlink.session = :session
and (rosterlink.jid like :jid
or rosterlink.rostername like :rostername)
order by groupname, rosterlink.jid
limit 3 offset 0';
$this->prepare(
'RosterLink',
array(
'session' => $this->_user,
'jid' => '%'.$key.'%',
'rostername' => '%'.$key.'%'
)
);
return $this->run('RosterContact');
}
function getRosterFrom() {
$this->_sql = '
select * from rosterlink

View file

@ -160,6 +160,32 @@ class MessageDAO extends SQL {
where session = :session
and (jidfrom = :jidfrom
or jidto = :jidto)
and type = \'chat\'
order by published desc';
if($limitr)
$this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
$this->prepare(
'Message',
array(
'session' => $this->_user,
'jidfrom' => $jid,
'jidto' => $jid
)
);
return $this->run('Message');
}
function getRoom($jid, $limitf = false, $limitr = false)
{
$this->_sql = '
select * from message
where session = :session
and (jidfrom = :jidfrom
or jidto = :jidto)
and type = \'groupchat\'
order by published desc';
if($limitr)

View file

@ -625,7 +625,36 @@ class PostnDAO extends SQL {
return $this->run('ContactPostn');
}
function exist($id) {
function search($key)
{
$this->_sql = '
select *, postn.aid from postn
left outer join contact on postn.aid = contact.jid
where (
(postn.origin in (select jid from rosterlink where session = :origin and rostersubscription in (\'both\', \'to\')) and node = \'urn:xmpp:microblog:0\')
or (postn.origin = :origin and node = \'urn:xmpp:microblog:0\')
or ((postn.origin, node) in (select server, node from subscription where jid = :origin))
)
and postn.node not like \'urn:xmpp:microblog:0:comments/%\'
and postn.node not like \'urn:xmpp:inbox\'
and upper(title) like upper(:title)
order by postn.published desc
limit 5 offset 0
';
$this->prepare(
'Postn',
array(
'origin' => $this->_user,
'title' => '%'.$key.'%'
)
);
return $this->run('ContactPostn');
}
function exist($id)
{
$this->_sql = '
select count(*) from postn
where postn.nodeid = :nodeid

View file

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

View file

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

View file

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

View file

@ -1,3 +1,4 @@
<?php $this->widget('Search');?>
<?php $this->widget('Upload'); ?>
<nav class="color dark">
@ -6,7 +7,6 @@
</nav>
<main>
<?php $this->widget('Header'); ?>
<section>
<?php $this->widget('Groups'); ?>
<?php $this->widget('Group'); ?>

View file

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

View file

@ -1,5 +1,6 @@
<?php $this->widget('Init');?>
<?php $this->widget('Upload');?>
<?php $this->widget('Search');?>
<nav class="color dark">
<?php $this->widget('Presence');?>

View file

@ -24,6 +24,10 @@
$this->addCss('grid.css');
$this->addCss('article.css');
$this->addCss('form.css');
$this->addCss('icon.css');
$this->addCss('dialog.css');
$this->addCss('card.css');
$this->addCss('table.css');
$this->addCss('color.css');
$this->addCss('block.css');
$this->addCss('menu.css');

View file

@ -23,7 +23,7 @@
top: 4rem;
float: right;
position: relative;
line-height: 3rem;
line-height: 2rem;
padding: 1rem;
width: 15rem;
box-sizing: border-box;

View file

@ -36,7 +36,6 @@ class Chat extends \Movim\Widget\Base
$this->registerEvent('muc_setconfig_handle', 'onRoomConfigSaved');
$this->registerEvent('bob_request_handle', 'onSticker');
//$this->registerEvent('muc_setsubject_handle', 'onRoomSubjectChanged');
//$this->registerEvent('presence', 'onPresence');
}
@ -129,8 +128,7 @@ class Chat extends \Movim\Widget\Base
function onConferenceSubject($packet)
{
$header = $this->prepareHeaderRoom($packet->content->jidfrom);
Header::fill($header);
$this->ajaxGetRoom($packet->content->jidfrom);
}
function onRoomConfig($packet)
@ -152,12 +150,7 @@ class Chat extends \Movim\Widget\Base
{
Notification::append(false, $this->__('chatroom.config_saved'));
}
/*
function onRoomSubjectChanged($packet)
{
Notification::append(false, $this->__('chatroom.suject_changed'));
}
*/
private function setState($array, $message)
{
list($from, $to) = $array;
@ -184,6 +177,10 @@ class Chat extends \Movim\Widget\Base
if($jid == null) {
RPC::call('movim_fill', 'chat_widget', $this->prepareEmpty());
} else {
$n = new Notification;
$n->ajaxCurrent('chat|'.$jid);
$n->ajaxClear('chat|'.$jid);
$chats = new Chats;
$chats->ajaxGetHistory($jid);
@ -441,32 +438,6 @@ class Chat extends \Movim\Widget\Base
->request();
}
/**
* @brief Prepare the contact header
*
* @param string $jid
*/
function prepareHeaderRoom($room)
{
$view = $this->tpl();
$md = new \Modl\MessageDAO;
$s = $md->getRoomSubject($room);
$cd = new \Modl\ConferenceDAO;
$c = $cd->get($room);
$pd = new \Modl\PresenceDAO;
$p = $pd->getMyPresenceRoom($room);
$view->assign('room', $room);
$view->assign('subject', $s);
$view->assign('presence', $p);
$view->assign('conference', $c);
return $view->draw('_chat_header_room', true);
}
function prepareChat($jid, $muc = false)
{
$view = $this->tpl();
@ -515,12 +486,17 @@ class Chat extends \Movim\Widget\Base
return $view->draw('_chat', true);
}
function prepareMessages($jid)
function prepareMessages($jid, $muc = false)
{
if(!$this->validateJid($jid)) return;
$md = new \Modl\MessageDAO;
$messages = $md->getContact(echapJid($jid), 0, $this->_pagination);
if($muc) {
$messages = $md->getRoom(echapJid($jid));
} else {
$messages = $md->getContact(echapJid($jid), 0, $this->_pagination);
}
if(is_array($messages)) {
$messages = array_reverse($messages);
@ -594,6 +570,10 @@ class Chat extends \Movim\Widget\Base
$message->publishedPrepared = prepareDate(strtotime($message->published), true, true);
if($message->delivered) {
$message->delivered = prepareDate(strtotime($message->delivered), true);
}
return $message;
}

View file

@ -14,14 +14,15 @@
<i class="zmdi zmdi-more-vert"></i>
</span>
<span class="control icon active" onclick="Rooms_ajaxExit('{$room}'); MovimTpl.hidePanel(); {if="$anon"}Presence_ajaxLogout(){/if}">
<i class="zmdi zmdi-close"></i>
</span>
{if="$c->supported('upload')"}
<span class="control icon active" onclick="Upload_ajaxRequest()">
<i class="zmdi zmdi-attachment-alt"></i>
</span>
{/if}
<span class="control icon active" onclick="Rooms_ajaxExit('{$room}'); MovimTpl.hidePanel(); {if="$anon"}Presence_ajaxLogout(){/if}">
<i class="zmdi zmdi-close"></i>
</span>
{if="$conference != null && $conference->name"}
<p class="line" title="{$room}">{$conference->name}</p>
@ -103,6 +104,14 @@
rows="1"
id="chat_textarea"
data-jid="{$jid}"
onkeydown="
if(event.keyCode == 38 && this.value == '') {
Chat_ajaxLast(this.dataset.jid);
} else if(event.keyCode == 40
&& (this.value == '' || Chat.edit == true)) {
Chat.clearReplace();
}
"
onkeypress="
if(event.keyCode == 13) {
if(event.shiftKey) {
@ -111,11 +120,6 @@
state = 0;
Chat.sendMessage(this.dataset.jid, {if="$muc"}true{else}false{/if});
return false;
} else if(event.keyCode == 38 && this.value == '') {
Chat_ajaxLast(this.dataset.jid);
} else if(event.keyCode == 40
&& (this.value == '' || Chat.edit == true)) {
Chat.clearReplace();
} else {
{if="!$muc"}
if(state == 0 || state == 2) {
@ -145,3 +149,4 @@
</li>
</ul>
</div>

View file

@ -11,7 +11,7 @@
position: fixed;
bottom: 0;
background-color: white;
width: 65%;
width: inherit;
max-width: 100%;
border-top: 1px solid rgba(0, 0, 0, 0.12);
}
@ -45,7 +45,7 @@
}
#chat_widget section {
padding-bottom: 1rem;
padding-bottom: 2rem;
}
#chat_widget li.oppose span.control {

View file

@ -158,7 +158,7 @@ var Chat = {
}
if(message.delivered) {
info.innerHTML = '<i class="zmdi zmdi-check"></i> ' + info.innerHTML;
info.innerHTML = '<i class="zmdi zmdi-check" title="' + message.delivered + '"></i> ' + info.innerHTML;
}
if(prepend) {

View file

@ -5,3 +5,4 @@
{$c->prepareEmpty()}
{/if}
</div>

View file

@ -120,7 +120,7 @@ class Chats extends \Movim\Widget\Base
if(!$this->validateJid($jid)) return;
$chats = Cache::c('chats');
if($chats == null) $chats = array();
if($chats == null) $chats = [];
unset($chats[$jid]);

View file

@ -14,7 +14,6 @@ var Chats = {
Chat_ajaxGet(this.dataset.jid);
Chats.reset(items);
Notification_ajaxClear('chat|' + this.dataset.jid);
Notification.current('chat|' + this.dataset.jid);
document.querySelector('#chat_widget').dataset.jid = this.dataset.jid;
movim_add_class(this, 'active');

View file

@ -1,10 +1,12 @@
<div title="{$c->__('page.profile')}">
{$c->prepareEmpty()}
{if="$jid"}
<script type="text/javascript">
MovimWebsocket.attach(function() {
Contact_ajaxGetContact('{$jid}');
});
</script>
{/if}
</div>
{if="$jid"}
<!--<script type="text/javascript">
MovimWebsocket.attach(function() {
Contact_ajaxGetContact('{$jid}');
});
</script>-->
{$c->prepareContact($jid)}
{else}
<div title="{$c->__('page.profile')}">
{$c->prepareEmpty()}
</div>
{/if}

View file

@ -13,10 +13,11 @@ use Moxl\Xec\Action\Pubsub\SetConfig;
use Moxl\Xec\Action\Pubsub\Delete;
use Respect\Validation\Validator;
use Cocur\Slugify\Slugify;
class Group extends \Movim\Widget\Base
{
private $_paging = 15;
private $_paging = 10;
private $_role = null;
function load()
@ -26,6 +27,7 @@ class Group extends \Movim\Widget\Base
$this->registerEvent('pubsub_getitemsid_handle', 'onItems', 'groups');
$this->registerEvent('pubsub_getitems_error', 'onItemsError', 'groups');
$this->registerEvent('pubsub_getitemsid_error', 'onItemsError', 'groups');
$this->registerEvent('pubsub_getmetadata_handle', 'onMetadata', 'groups');
$this->registerEvent('pubsub_subscribe_handle', 'onSubscribed');
$this->registerEvent('pubsub_unsubscribe_handle', 'onUnsubscribed');
@ -69,7 +71,9 @@ class Group extends \Movim\Widget\Base
$html = $view->draw('_group_ticker', true);
RPC::call('MovimTpl.fill', '#group_widget.'.stringToUri($server.'_'.$node), $html);
$slugify = new Slugify();
RPC::call('MovimTpl.fill', '#group_widget.'.$slugify->slugify($server.'_'.$node), $html);
RPC::call('Group.clearLoad');
RPC::call('MovimTpl.showPanel');
}
@ -96,6 +100,13 @@ class Group extends \Movim\Widget\Base
}
}
function onMetadata($packet)
{
list($server, $node) = $packet->content;
RPC::call('MovimTpl.fill', '#group_widget > header', $this->prepareHeader($server, $node));
}
function onAffiliations($packet)
{
list($affiliations, $server, $node) = array_values($packet->content);
@ -105,7 +116,7 @@ class Group extends \Movim\Widget\Base
$this->_role = (string)$r[1];
}
Header::fill($this->prepareHeader($server, $node));
RPC::call('MovimTpl.fill', '#group_widget > header', $this->prepareHeader($server, $node));
//if(isset($this->_role)
//&& ($this->_role == 'owner' || $this->_role == 'publisher')) {
@ -198,7 +209,9 @@ class Group extends \Movim\Widget\Base
$view->assign('node', $node);
$html .= $view->draw('_group_publish', true);
RPC::call('MovimTpl.fill', '#group_widget.'.stringToUri($server.'_'.$node), $html);
$slugify = new Slugify();
RPC::call('MovimTpl.fill', '#group_widget.'.$slugify->slugify($server.'_'.$node).' > div.card', $html);
RPC::call('Group.enableVideos');
unset($html);
}
@ -257,7 +270,9 @@ class Group extends \Movim\Widget\Base
{
if(!$this->validateServerNode($server, $node)) return;
RPC::call('Group.addLoad', stringToUri($server.'_'.$node));
$slugify = new Slugify();
RPC::call('Group.addLoad', $slugify->slugify($server.'_'.$node));
$r = new GetItemsId;
$r->setTo($server)
@ -269,7 +284,7 @@ class Group extends \Movim\Widget\Base
function ajaxGetHistory($server, $node, $page)
{
$html = $this->prepareGroup($server, $node, $page);
RPC::call('movim_append', 'group_widget', $html);
RPC::call('MovimTpl.append', '#group_widget > div', $html);
RPC::call('Group.enableVideos');
}
@ -365,7 +380,8 @@ class Group extends \Movim\Widget\Base
function ajaxClear()
{
$html = $this->prepareEmpty();
RPC::call('movim_fill', 'group_widget', $html);
RPC::call('MovimTpl.fill', '#group_widget header', '');
RPC::call('MovimTpl.fill', '#group_widget > div', $html);
}
function prepareEmpty()
@ -417,6 +433,7 @@ class Group extends \Movim\Widget\Base
$view->assign('page', $page);
$view->assign('posts', $posts);
$view->assign('paging', $this->_paging);
$html = $view->draw('_group_posts', true);
return $html;

View file

@ -1,65 +1,53 @@
<div>
<ul class="list middle">
<li>
<span class="primary on_desktop icon"><i class="zmdi zmdi-pages"></i></span>
<p>
{$c->__('page.groups')}
</p>
</li>
</ul>
</div>
<div>
<ul class="list middle">
<li>
<span id="back" class="primary icon active" onclick="MovimTpl.hidePanel(); Group_ajaxClear(); Groups_ajaxHeader();">
<i class="zmdi zmdi-arrow-back"></i>
<ul class="list middle">
<li>
<span id="back" class="primary icon active" onclick="MovimTpl.hidePanel(); Group_ajaxClear();">
<i class="zmdi zmdi-arrow-back"></i>
</span>
{if="$role == 'owner'"}
<span class="control show_context_menu icon active">
<i class="zmdi zmdi-more-vert"></i>
</span>
{if="$role == 'owner'"}
<span class="control show_context_menu icon active">
<i class="zmdi zmdi-more-vert"></i>
</span>
{/if}
{if="$subscription == null"}
<span class="control icon active" title="{$c->__('group.subscribe')}"
onclick="Group_ajaxAskSubscribe('{$item->server}', '{$item->node}')">
<i class="zmdi zmdi-bookmark-outline"></i>
</span>
{else}
<span class="control icon active" title="{$c->__('group.unsubscribe')}"
onclick="Group_ajaxAskUnsubscribe('{$item->server}', '{$item->node}')">
<i class="zmdi zmdi-bookmark"></i>
</span>
{/if}
<p class="line">
{if="$item != null"}
{if="$item->name"}
{$item->name}
{else}
{$item->node}
{/if}
{/if}
{if="$subscription == null"}
<span class="control icon active" title="{$c->__('group.subscribe')}"
onclick="Group_ajaxAskSubscribe('{$item->server}', '{$item->node}')">
<i class="zmdi zmdi-bookmark-outline"></i>
</span>
{else}
<span class="control icon active" title="{$c->__('group.unsubscribe')}"
onclick="Group_ajaxAskUnsubscribe('{$item->server}', '{$item->node}')">
<i class="zmdi zmdi-bookmark"></i>
</span>
{/if}
<p class="line">
{if="$item != null"}
{if="$item->name"}
{$item->name}
{else}
{$item->node}
{/if}
</p>
{if="$item->description"}
<p class="line" title="{$item->description|strip_tags}">
{$item->description|strip_tags}
</p>
{else}
<p class="line">{$item->server}</p>
{/if}
</p>
{if="$item->description"}
<p class="line" title="{$item->description|strip_tags}">
{$item->description|strip_tags}
</p>
{else}
<p class="line">{$item->server}</p>
{/if}
</li>
</ul>
{if="$role == 'owner'"}
<ul class="list context_menu active">
<li onclick="Group_ajaxGetConfig('{$item->server}', '{$item->node}')">
<p class="normal">{$c->__('group.configuration')}</p>
</li>
<li onclick="Group_ajaxGetSubscriptions('{$item->server}', '{$item->node}', true)">
<p class="normal">{$c->__('group.subscriptions')}</p>
</li>
<li onclick="Group_ajaxDelete('{$item->server}', '{$item->node}')">
<p class="normal">{$c->__('button.delete')}</p>
</li>
</ul>
{if="$role == 'owner'"}
<ul class="list context_menu active">
<li onclick="Group_ajaxGetConfig('{$item->server}', '{$item->node}')">
<p class="normal">{$c->__('group.configuration')}</p>
</li>
<li onclick="Group_ajaxGetSubscriptions('{$item->server}', '{$item->node}', true)">
<p class="normal">{$c->__('group.subscriptions')}</p>
</li>
<li onclick="Group_ajaxDelete('{$item->server}', '{$item->node}')">
<p class="normal">{$c->__('button.delete')}</p>
</li>
</ul>
{/if}
</div>
{/if}

View file

@ -1,3 +1,6 @@
{if="$page == 0"}
<br />
{/if}
{loop="$posts"}
{$c->preparePost($value)}
{/loop}

View file

@ -1,12 +1,15 @@
<div id="group_widget" class="card shadow spinner" style="background-color: #EEE;">
{$c->prepareEmpty()}
{if="$server && $node"}
<script type="text/javascript">
MovimWebsocket.attach(function() {
Group_ajaxGetItems('{$server}', '{$node}');
Group_ajaxGetMetadata('{$server}', '{$node}');
Group_ajaxGetAffiliations('{$server}', '{$node}');
});
</script>
{/if}
<div id="group_widget" class="spinner" style="background-color: #EEE;">
<header class="fixed">{$header}</header>
<div class="card shadow">
{$c->prepareEmpty()}
{if="$server && $node"}
<script type="text/javascript">
MovimWebsocket.attach(function() {
Group_ajaxGetItems('{$server}', '{$node}');
Group_ajaxGetMetadata('{$server}', '{$node}');
Group_ajaxGetAffiliations('{$server}', '{$node}');
});
</script>
{/if}
</div>
</div>

View file

@ -6,6 +6,8 @@ use Respect\Validation\Validator;
use Moxl\Xec\Action\Pubsub\Create;
use Moxl\Xec\Action\Pubsub\TestCreate;
use Cocur\Slugify\Slugify;
class Groups extends \Movim\Widget\Base
{
private $_list_server;
@ -127,7 +129,14 @@ class Groups extends \Movim\Widget\Base
return;
}
$uri = stringToUri($form->name->value);
$slugify = new Slugify();
$uri = $slugify->slugify($form->name->value);
if($uri == '') {
Notification::append(null, $this->__('groups.name_error'));
return;
}
$c = new Create;
$c->setTo($server)->setNode($uri)->setData($form->name->value)
@ -182,7 +191,7 @@ class Groups extends \Movim\Widget\Base
*/
private function validateServer($server)
{
$validate_server = Validator::noWhitespace()->alnum('.')->length(6, 40);
$validate_server = Validator::noWhitespace()->alnum('.-_')->length(6, 40);
return ($validate_server->validate($server));
}

View file

@ -1,6 +1,6 @@
<section>
<form name="groupadd">
<h3>{$c->__('groups.add')}</h3>
<form name="groupadd" onsubmit="return false;">
<h3>{$c->__('groups.add', $server)}</h3>
<div>
<input name="name" placeholder="{$c->__('groups.name_example')}" type="text" required />

View file

@ -1,8 +1,24 @@
<header>
<ul class="list middle">
<li>
<span class="primary icon icon gray active" onclick="Groups_ajaxSubscriptions()">
<i class="zmdi zmdi-arrow-back"></i>
</span>
{if="count($nodes) > 0"}
<span class="control icon gray">
{$nodes|count}
</span>
{/if}
<p class="center">{$c->__('page.groups')}</p>
<p class="center line">{$server}</p>
</li>
</ul>
</header>
<ul class="list middle divided spaced active all">
<li class="subheader" onclick="Groups_ajaxSubscriptions()">
<!--<li class="subheader" >
<span class="primary icon"><i class="zmdi zmdi-arrow-back"></i></span>
<p class="normal"><span class="info">{$nodes|count}</span>{$server}</p>
</li>
<p class="normal">{$server}</p>
</li>-->
{loop="$nodes"}
<li
class="

View file

@ -1,3 +1,22 @@
<header>
<ul class="list middle">
<li>
<span id="menu" class="primary on_mobile icon active gray" onclick="MovimTpl.toggleMenu()">
<i class="zmdi zmdi-menu"></i>
</span>
<span class="primary icon on_desktop icon gray">
<i class="zmdi zmdi-bookmark"></i>
</span>
{if="count($subscriptions) > 0"}
<span class="control icon gray">
{$subscriptions|count}
</span>
{/if}
<p class="center">{$c->__('page.groups')}</p>
<p class="center">{$c->__('groups.subscriptions')}</p>
</li>
</ul>
</header>
{if="$subscriptions == null"}
<ul class="thick">
<div class="placeholder icon bookmark">

View file

@ -4,7 +4,7 @@ contact_post = Contact post
empty_text1 = "Here you will be able to manage all your subscriptions."
empty_text2 = "You don't have any group subscriptions yet."
subscriptions = My Subscriptions
add = Create a new Group
add = Create a new Group on %s
name = Group name
name_example = My Little Pony - Fan Club
created = Group created successfully

View file

@ -153,10 +153,10 @@ class Login extends \Movim\Widget\Base
function ajaxLogin($form)
{
$login = $form->login->value;
$password = $form->pass->value;
$username = $form->username->value;
$password = $form->password->value;
$this->doLogin($login, $password);
$this->doLogin($username, $password);
}
function ajaxHTTPLogin($login, $password)

View file

@ -2,8 +2,8 @@ var Login = {
domain : '@movim.eu',
submitted : false,
fillExample : function(login, pass) {
document.querySelector('#login').value = login;
document.querySelector('#pass').value = pass;
document.querySelector('input#username').value = login;
document.querySelector('input#password').value = pass;
},
/**
@ -11,24 +11,25 @@ var Login = {
*/
init : function() {
// The form submission event
form = document.querySelector('form[name="login"]');
form.onsubmit = function(e) {
document.body.addEventListener('submit', function(e) {
e.preventDefault();
Login.submitted = true;
// We register the socket
MovimWebsocket.connection.register(this.querySelector('input#login').value.replace(/.*@/, ""));
MovimWebsocket.connection.register(this.querySelector('input#username').value.replace(/.*@/, ""));
var button = this.querySelector('input[type=submit]');
button.value = button.dataset.loading;
localStorage.username = document.querySelector('#login').value;
localStorage.username = document.querySelector('input#username').value;
Login.rememberSession(localStorage.username);
// A fallback security
setTimeout("MovimWebsocket.unregister()", 20000);
}
return true;
}, false);
},
refresh: function(){
@ -75,14 +76,14 @@ var Login = {
else{
Login.toForm();
document.querySelector('#login').value = jid;
document.querySelector('input#username').value = jid;
document.querySelector('input#complete').value = jid;
document.querySelector('#pass').value = "";
document.querySelector('input#password').value = "";
if(jid != '') {
document.querySelector('#pass').focus();
document.querySelector('input#password').focus();
} else {
document.querySelector('#login').focus();
document.querySelector('input#username').focus();
}
}
},
@ -118,7 +119,7 @@ var Login = {
toForm : function() {
movim_remove_class('#login_widget', 'choose');
// Empty login field
document.querySelector('#login').value = "";
document.querySelector('input#username').value = "";
},
/**
@ -127,7 +128,8 @@ var Login = {
post : function(jid, url) {
Login.rememberSession(jid);
localStorage.postStart = 1;
movim_reload(url);
movim_redirect(url);
},
/**
@ -141,7 +143,7 @@ var Login = {
MovimWebsocket.attach(function()
{
if(localStorage.username != null)
document.querySelector('#login').value = localStorage.username;
document.querySelector('input#username').value = localStorage.username;
Login.init();
@ -173,7 +175,7 @@ MovimWebsocket.register(function()
movim_add_onload(function() {
// We had the autocomplete system
var login = document.querySelector('input#login');
var login = document.querySelector('input#username');
login.addEventListener('input', function() {
if(this.value.indexOf('@') == -1) {
// TODO allow another server here

View file

@ -20,17 +20,18 @@
<h3>{$c->__('page.login')}</h3>
<form
data-action="{$submit}"
method="post" action="login"
name="login">
<div>
<input type="text" id="complete" tabindex="-1"/>
<input type="email" name="login" id="login" autofocus required disabled
<input type="email" name="username" id="username" autofocus required
placeholder="username@server.com"/>
<label for="login">{$c->__('form.username')}</label>
<label for="username">{$c->__('form.username')}</label>
</div>
<div>
<input type="password" name="pass" id="pass" autocomplete="off" required disabled
<input type="password" name="password" id="password" required
placeholder="{$c->__('form.password')}"/>
<label for="pass">{$c->__('form.password')}</label>
<label for="password">{$c->__('form.password')}</label>
</div>
<div>
<ul class="list thin">

View file

@ -13,7 +13,7 @@
<li {if="$type == 'all'"}class="active"{/if}><a href="#" onclick="Menu_ajaxGetAll()">{$c->__('menu.all')}</a></li>
<li {if="$type == 'news'"}class="active"{/if} ><a href="#" onclick="Menu_ajaxGetNews()" title="{$c->__('page.news')}"><i class="zmdi zmdi-pages"></i></a></li>
<li {if="$type == 'feed'"}class="active"{/if}><a href="#" onclick="Menu_ajaxGetFeed()" title="{$c->__('page.feed')}"><i class="zmdi zmdi-accounts"></i></a></li>
<li {if="$type == 'me'"}class="active"{/if}><a href="#" onclick="Menu_ajaxGetMe()" title="{$c->__('menu.mine')}"><i class="zmdi zmdi-portable-wifi"></i></a></li>
<li {if="$type == 'me'"}class="active"{/if}><a href="#" onclick="Menu_ajaxGetMe()" title="{$c->__('menu.mine')}"><i class="zmdi zmdi-edit"></i></a></li>
</ul>
</li>
</ul>
@ -46,24 +46,35 @@
+18
</span>
{elseif="$picture != null"}
<span class="primary icon thumb" style="background-image: url({$picture});"></span>
<span class="primary icon thumb color white" style="background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.3) 100%), url({$picture});">
{if="$value->isPublic()"}
<i title="{$c->__('menu.public')}" class="zmdi zmdi-portable-wifi"></i>
{/if}
</span>
{elseif="$value->node == 'urn:xmpp:microblog:0'"}
{$url = $value->getContact()->getPhoto('l')}
{if="$url"}
<span class="primary icon thumb" style="background-image: url({$url});">
<span class="primary icon thumb color white" style="background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.3) 100%), url({$url});">
{if="$value->isPublic()"}
<i title="{$c->__('menu.public')}" class="zmdi zmdi-portable-wifi"></i>
{/if}
</span>
{else}
<span class="primary icon thumb color {$value->getContact()->jid|stringToColor}">
<i class="zmdi zmdi-account"></i>
{if="$value->isPublic()"}
<i title="{$c->__('menu.public')}" class="zmdi zmdi-portable-wifi"></i>
{else}
<i class="zmdi zmdi-account"></i>
{/if}
</span>
{/if}
{else}
<span class="primary icon thumb color {$value->node|stringToColor}">{$value->node|firstLetterCapitalize}</span>
{/if}
{if="$value->isPublic()"}
<span class="control icon gray" title="{$c->__('menu.public')}">
<i class="zmdi zmdi-portable-wifi"></i>
<span class="primary icon thumb color {$value->node|stringToColor}">
{if="$value->isPublic()"}
<i title="{$c->__('menu.public')}" class="zmdi zmdi-portable-wifi"></i>
{else}
{$value->node|firstLetterCapitalize}
{/if}
</span>
{/if}
@ -76,15 +87,15 @@
{if="$value->node == 'urn:xmpp:microblog:0'"}
<a href="{$c->route('contact', $value->getContact()->jid)}">
<i class="zmdi zmdi-account"></i> {$value->getContact()->getTrueName()}
</a>
</a>
{else}
{$value->origin} /
<a href="{$c->route('group', array($value->origin, $value->node))}">
<i class="zmdi zmdi-pages"></i> {$value->node}
</a>
</a>
{/if}
{$value->published|strtotime|prepareDate}
{if="$value->published != $value->updated"}<i class="zmdi zmdi-edit"></i>{/if}
<span class="info">
{$value->published|strtotime|prepareDate:true,true}
</span>
</p>
<p>{$value->contentcleaned|stripTags}</p>
</li>

View file

@ -18,28 +18,34 @@
<p class="normal">{$c->__('page.home')}</p>
</li>
</a>-->
<a class="classic {if="!$c->supported('pubsub')"}disabled{/if}" href="{$c->route('news')}">
<a class="classic {if="!$c->supported('pubsub')"}disabled{/if}"
href="{$c->route('news')}"
title="{$c->__('page.news')}">
<li {if="$page == 'news'"}class="active"{/if}>
<span class="primary icon"><i class="zmdi zmdi-receipt"></i></span>
<span data-key="news" class="counter"></span>
<p class="normal">{$c->__('page.news')}</p>
</li>
</a>
<a class="classic" href="{$c->route('contact')}">
<a class="classic" href="{$c->route('contact')}"
title="{$c->__('page.contacts')}">
<li {if="$page == 'contact'"}class="active"{/if}>
<span class="primary icon"><i class="zmdi zmdi-accounts"></i></span>
<span data-key="invite" class="counter"></span>
<p class="normal">{$c->__('page.contacts')}</p>
</li>
</a>
<a class="classic {if="!$c->supported('pubsub')"}disabled{/if}" href="{$c->route('group')}">
<a class="classic {if="!$c->supported('pubsub')"}disabled{/if}"
href="{$c->route('group')}"
title="{$c->__('page.groups')}">
<li {if="$page == 'group'"}class="active"{/if}>
<span class="primary icon"><i class="zmdi zmdi-pages"></i></span>
<span class="counter"></span>
<p class="normal">{$c->__('page.groups')}</p>
</li>
</a>
<a class="classic" href="{$c->route('chat')}">
<a class="classic" href="{$c->route('chat')}"
title="{$c->__('page.chats')}">
<li {if="$page == 'chat'"}class="active"{/if}>
<span class="primary icon"><i class="zmdi zmdi-comments"></i></span>
<span data-key="chat" class="counter"></span>
@ -49,10 +55,15 @@
</ul>
<ul class="list divided oppose active">
<li class="subheader">
<p>{$c->__('page.account')}</p>
<li onclick="Search_ajaxRequest()">
<span class="primary icon">
<i class="zmdi zmdi-search"></i>
</span>
<p class="normal">{$c->__('button.search')}</p>
</li>
<a class="classic {if="!$c->supported('pubsub')"}disabled{/if}" href="{$c->route('conf')}">
<a class="classic {if="!$c->supported('pubsub')"}disabled{/if}"
href="{$c->route('conf')}"
title="{$c->__('page.configuration')}">
<li>
<span class="primary icon">
<i class="zmdi zmdi-settings"></i>
@ -60,7 +71,9 @@
<p class="normal">{$c->__('page.configuration')}</p>
</li>
</a>
<a class="classic on_desktop" href="{$c->route('help')}">
<a class="classic on_desktop"
href="{$c->route('help')}"
title="{$c->__('page.help')}">
<li>
<span class="primary icon">
<i class="zmdi zmdi-help"></i>
@ -68,7 +81,8 @@
<p class="normal">{$c->__('page.help')}</p>
</li>
</a>
<li onclick="Presence_ajaxLogout()">
<li onclick="Presence_ajaxLogout()"
title="{$c->__('status.disconnect')}">
<span class="primary icon"><i class="zmdi zmdi-sign-in"></i></span>
<p class="normal">{$c->__('status.disconnect')}</p>
</li>

View file

@ -18,28 +18,33 @@ class Notification extends \Movim\Widget\Base
* @param integer $action An action
* @return void
*/
static function append($key = null, $title, $body = null, $picture = null, $time = 2, $action = null)
static function append($key = null, $title = null, $body = null, $picture = null, $time = 2, $action = null)
{
// In this case we have an action confirmation
if($key == null) {
if($key == null && $title != null) {
RPC::call('Notification.toast', $title);
return;
}
if($picture == null) {
$picture = BASE_URI . '/themes/material/img/app/128.png';
}
$session = Session::start();
$notifs = $session->get('notifs');
RPC::call('Notification.desktop', $title, $body, $picture, $action);
if($title != null)
RPC::call('Notification.desktop', $title, $body, $picture, $action);
$notifs_key = $session->get('notifs_key');
if($notifs == null) $notifs = array();
if($notifs == null) $notifs = [];
$explode = explode('|', $key);
$first = reset($explode);
// What we receive is not what it's on the screen on Android
if($key != null && $key != $notifs_key) {
if($key != null && $key != $notifs_key && $title != null) {
RPC::call('Notification.android', $title, $body, $picture, $action);
}
@ -63,8 +68,10 @@ class Notification extends \Movim\Widget\Base
RPC::call('Notification.counter', $key, $notifs[$key]);
}
$n = new Notification;
RPC::call('Notification.snackbar', $n->prepareSnackbar($title, $body, $picture, $action), $time);
if($title != null) {
$n = new Notification;
RPC::call('Notification.snackbar', $n->prepareSnackbar($title, $body, $picture, $action), $time);
}
$session->set('notifs', $notifs);
}

View file

@ -73,7 +73,6 @@
<i class="zmdi zmdi-account"></i> {$value->getContact()->getTrueName()}
</a>
{$value->published|strtotime|prepareDate}
{if="$value->published != $value->updated"}<i class="zmdi zmdi-edit"></i>{/if}
</p>
<p>

View file

@ -39,12 +39,12 @@ class Publish extends \Movim\Widget\Base
{
list($to, $node, $id) = array_values($packet->content);
RPC::call('Publish.enableSend');
// Only for the microblog for the moment
//if($node == 'urn:xmpp:microblog:0') {
$this->ajaxCreateComments($to, $id);
//}
RPC::call('movim_redirect', Route::urlize('news', $id));
}
function onTestPublish($packet)

View file

@ -13,12 +13,30 @@ class Rooms extends \Movim\Widget\Base
{
$this->addjs('rooms.js');
$this->addcss('rooms.css');
$this->registerEvent('message', 'onMessage');
$this->registerEvent('bookmark_set_handle', 'onBookmark');
$this->registerEvent('presence_muc_handle', 'onConnected');
$this->registerEvent('presence_unavailable_handle', 'onDisconnected');
$this->registerEvent('presence_muc_errorconflict', 'onConflict');
}
function onMessage($packet)
{
$message = $packet->content;
if($message->session == $message->jidto
&& $message->type == 'groupchat') {
Notification::append(
'chat|'.$message->jidfrom,
null,
$message->body,
null,
0,
null
);
}
}
function onBookmark()
{
$this->refreshRooms();

View file

@ -10,6 +10,7 @@
<li data-jid="{$value->conference}"
{if="$value->nick != null"} data-nick="{$value->nick}" {/if}
class="room {if="$value->connected"}online{/if}">
<span data-key="chat|{$value->conference}" class="counter"></span>
{if="$value->connected"}
<span class="primary icon small bubble color {$value->name|stringToColor}"><i class="zmdi zmdi-accounts"></i></span>
{else}

View file

@ -17,9 +17,9 @@
</span>
{/if}
{if="$value->mucaffiliation =='owner'"}
<div class="control">
<i class="zmdi zmdi-beenhere"></i>
</div>
<span class="control icon gray">
<i class="zmdi zmdi-star"></i>
</span>
{/if}
{if="$value->mucjid && strpos($value->mucjid, '/') == false && !$c->supported('anonymous')"}
<p class="line normal">

View file

@ -9,7 +9,9 @@ var Rooms = {
if(items[i].dataset.jid != null) {
items[i].onclick = function(e) {
Chats.refresh();
Notification.current('chat');
Notification_ajaxClear('chat|' + this.dataset.jid);
Notification.current('chat|' + this.dataset.jid);
if(!movim_has_class(this, 'online')) {
if(this.dataset.nick != null) {

View file

@ -0,0 +1,61 @@
<?php
use Respect\Validation\Validator;
use Modl\PostnDAO;
use Modl\ContactDAO;
class Search extends \Movim\Widget\Base
{
function load()
{
$this->addjs('search.js');
$this->addcss('search.css');
}
function ajaxRequest()
{
$view = $this->tpl();
$view->assign('empty', $this->prepareSearch(''));
Dialog::fill($view->draw('_search', true));
RPC::call('Search.init');
}
function prepareSearch($key)
{
$view = $this->tpl();
$validate_subject = Validator::stringType()->length(1, 15);
if(!$validate_subject->validate($key)) {
$view->assign('empty', true);
} else {
$view->assign('empty', false);
$pd = new PostnDAO;
$posts = $pd->search($key);
$view->assign('posts', $posts);
$cd = new ContactDAO;
$contacts = $cd->search($key);
$view->assign('contacts', $contacts);
if(!$posts && !$contacts) $view->assign('empty', true);
}
return $view->draw('_search_results', true);
}
function ajaxSearch($key)
{
RPC::call('MovimTpl.fill', '#results', $this->prepareSearch($key));
}
function ajaxChat($jid)
{
$contact = new Contact;
$contact->ajaxChat($jid);
}
function display()
{
}
}

View file

@ -0,0 +1,20 @@
<section id="search">
<ul class="list">
<li>
<span class="primary icon gray">
<i class="zmdi zmdi-search"></i>
</span>
<form name="search" onsubmit="return false;">
<div>
<input name="keyword" placeholder="{$c->__('search.keyword')}" onkeyup="Search_ajaxSearch(this.value);" type="text">
</div>
</form>
</li>
</ul>
<div id="results">{$empty}</div>
</section>
<div>
<a onclick="Dialog.clear(); Upload.xhr.abort();" class="button flat">
{$c->__('button.close')}
</a>
</div>

View file

@ -0,0 +1,60 @@
{if="$empty == true"}
<div class="placeholder icon search">
<h4>{$c->__('search.subtitle')}</h4>
</div>
{else}
<ul class="list active">
{if="$posts"}
<li class="subheader"><p>{$c->__('page.news')}</p></li>
{/if}
{loop="$posts"}
<li onclick="movim_reload('{$c->route('news', $value->nodeid)}')">
{if="$value->title != null"}
<p class="line">{$value->title}</p>
{else}
<p class="line">{$c->__('menu.contact_post')}</p>
{/if}
<p>
{if="$value->node == 'urn:xmpp:microblog:0'"}
<a href="{$c->route('contact', $value->getContact()->jid)}">
<i class="zmdi zmdi-account"></i> {$value->getContact()->getTrueName()}
</a>
{else}
<a href="{$c->route('group', array($value->origin, $value->node))}">
<i class="zmdi zmdi-pages"></i> {$value->node}
</a>
{/if}
<span class="info">
{$value->published|strtotime|prepareDate:true,true}
</span>
</p>
</li>
{/loop}
{if="$contacts"}
<li class="subheader"><p>{$c->__('page.contacts')}</p></li>
{/if}
{loop="$contacts"}
<li>
{$url = $value->getPhoto('s')}
{if="$url"}
<span class="primary icon bubble">
<img src="{$url}">
</span>
{else}
<span class="primary icon bubble color {$valu->jid|stringToColor}">
<i class="zmdi zmdi-account"></i>
</span>
{/if}
<span class="control icon active gray" onclick="movim_reload('{$c->route('contact', $value->jid)}')">
<i class="zmdi zmdi-account"></i>
</span>
<span class="control icon active gray" onclick="Search_ajaxChat('{$value->jid}')">
<i class="zmdi zmdi-comment-text-alt"></i>
</span>
<p class="line">{$value->getTrueName()}</p>
<p class="line">{$value->jid}</p>
</li>
{/loop}
</ul>
{/if}

View file

@ -0,0 +1,3 @@
[search]
keyword = What are you looking for?
subtitle = Open me using Ctrl + M

View file

@ -0,0 +1,16 @@
#search #results {
padding: 0;
}
#search form > div:not(.clear):not(.control) {
min-height: 8rem;
}
#search form > div > input:not([type="submit"]) {
padding-top: 3.7rem;
margin-bottom: 0;
}
#search form > div:not(.control) {
top: -1rem;
}

View file

@ -0,0 +1,11 @@
var Search = {
init : function() {
document.querySelector('input[name=keyword]').focus();
}
}
document.addEventListener('keydown', function(e) {
if (e.keyCode == 77 && e.ctrlKey) {
Search_ajaxRequest();
}
});

View file

@ -0,0 +1,2 @@

View file

@ -123,6 +123,19 @@ class Stickers extends \Movim\Widget\Base
Dialog::fill($view->draw('_stickers_smiley', true));
}
/**
* @brief Show the smiley list
*/
function ajaxSmileyTwo($to)
{
if(!$this->validateJid($to)) return;
$view = $this->tpl();
$view->assign('jid', $to);
$view->assign('icon', $this->respath('stickers').'/icon.png');
Dialog::fill($view->draw('_stickers_smiley_two', true));
}
/**
* @brief Get the path of a emoji
*/

View file

@ -6,6 +6,9 @@
<li onclick="Stickers_ajaxSmiley('{$jid}')">
<a href="#"><img alt=":smiley:" class="emoji medium" src="{$c->getSmileyPath('1f603')}"></a>
</li>
<li onclick="Stickers_ajaxSmileyTwo('{$jid}')">
<a href="#"><img alt=":smiley:" class="emoji medium" src="{$c->getSmileyPath('1f44d')}"></a>
</li>
</ul>
<ul class="list flex third active">
{loop="$stickers"}

View file

@ -6,80 +6,83 @@
<li onclick="Stickers_ajaxSmiley('{$jid}')" class="active">
<a href="#"><img alt=":smiley:" class="emoji medium" src="{$c->getSmileyPath('1f603')}"></a>
</li>
<li onclick="Stickers_ajaxSmileyTwo('{$jid}')">
<a href="#"><img alt=":smiley:" class="emoji medium" src="{$c->getSmileyPath('1f44d')}"></a>
</li>
</ul>
<table class="emojis">
<tbody>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="😂"><img alt=":joy:" class="emoji large" src="{$c->getSmileyPath('1f602')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😃"><img alt=":smiley:" class="emoji large" src="{$c->getSmileyPath('1f603')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😄"><img alt=":smile:" class="emoji large" src="{$c->getSmileyPath('1f604')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😆"><img alt=":laughing:" class="emoji large" src="{$c->getSmileyPath('1f606')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😍"><img alt=":heart_eyes:" class="emoji large" src="{$c->getSmileyPath('1f60d')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😉"><img alt=":wink:" class="emoji large" src="{$c->getSmileyPath('1f609')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😀"><img class="emoji large" src="{$c->getSmileyPath('1f600')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😁"><img class="emoji large" src="{$c->getSmileyPath('1f601')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😂"><img class="emoji large" src="{$c->getSmileyPath('1f602')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😃"><img class="emoji large" src="{$c->getSmileyPath('1f603')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😄"><img class="emoji large" src="{$c->getSmileyPath('1f604')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😅"><img class="emoji large" src="{$c->getSmileyPath('1f605')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="😠"><img alt=":angry:" class="emoji large" src="{$c->getSmileyPath('1f620')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😜"><img alt=":stuck_out_tongue_winking_eye:" class="emoji large" src="{$c->getSmileyPath('1f61c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😝"><img alt=":stuck_out_tongue_closed_eyes:" class="emoji large" src="{$c->getSmileyPath('1f61d')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😒"><img alt=":unamused:" class="emoji large" src="{$c->getSmileyPath('1f612')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😓"><img alt=":sweat:" class="emoji large" src="{$c->getSmileyPath('1f613')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😖"><img alt=":confounded:" class="emoji large" src="{$c->getSmileyPath('1f616')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😆"><img class="emoji large" src="{$c->getSmileyPath('1f606')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😇"><img class="emoji large" src="{$c->getSmileyPath('1f607')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😈"><img class="emoji large" src="{$c->getSmileyPath('1f608')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😉"><img class="emoji large" src="{$c->getSmileyPath('1f609')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😊"><img class="emoji large" src="{$c->getSmileyPath('1f60a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😋"><img class="emoji large" src="{$c->getSmileyPath('1f60b')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="😢"><img alt=":cry:" class="emoji large" src="{$c->getSmileyPath('1f622')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😤"><img alt=":triumph:" class="emoji large" src="{$c->getSmileyPath('1f624')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😥"><img alt=":disappointed_relieved:" class="emoji large" src="{$c->getSmileyPath('1f625')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😪"><img alt=":sleepy:" class="emoji large" src="{$c->getSmileyPath('1f62a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😭"><img alt=":sob:" class="emoji large" src="{$c->getSmileyPath('1f62d')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😱"><img alt=":scream:" class="emoji large" src="{$c->getSmileyPath('1f631')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😌"><img class="emoji large" src="{$c->getSmileyPath('1f60c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😍"><img class="emoji large" src="{$c->getSmileyPath('1f60d')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😎"><img class="emoji large" src="{$c->getSmileyPath('1f60e')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😏"><img class="emoji large" src="{$c->getSmileyPath('1f60f')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😐"><img class="emoji large" src="{$c->getSmileyPath('1f610')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😑"><img class="emoji large" src="{$c->getSmileyPath('1f611')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🍌"><img alt=":banana:" class="emoji large" src="{$c->getSmileyPath('1f34c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍎"><img alt=":apple:" class="emoji large" src="{$c->getSmileyPath('1f34e')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🌼"><img alt=":blossom:" class="emoji large" src="{$c->getSmileyPath('1f33c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🌵"><img alt=":cactus:" class="emoji large" src="{$c->getSmileyPath('1f335')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🌹"><img alt=":rose:" class="emoji large" src="{$c->getSmileyPath('1f339')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍄"><img alt=":mushroom:" class="emoji large" src="{$c->getSmileyPath('1f344')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😒"><img class="emoji large" src="{$c->getSmileyPath('1f612')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😓"><img class="emoji large" src="{$c->getSmileyPath('1f613')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😔"><img class="emoji large" src="{$c->getSmileyPath('1f614')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😕"><img class="emoji large" src="{$c->getSmileyPath('1f615')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😖"><img class="emoji large" src="{$c->getSmileyPath('1f616')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😗"><img class="emoji large" src="{$c->getSmileyPath('1f617')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🍔"><img alt=":hamburger:" class="emoji large" src="{$c->getSmileyPath('1f354')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍕"><img alt=":pizza:" class="emoji large" src="{$c->getSmileyPath('1f355')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍗"><img alt=":poultry_leg:" class="emoji large" src="{$c->getSmileyPath('1f357')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍚"><img alt=":rice:" class="emoji large" src="{$c->getSmileyPath('1f35a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍜"><img alt=":ramen:" class="emoji large" src="{$c->getSmileyPath('1f35c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍣"><img alt=":sushi:" class="emoji large" src="{$c->getSmileyPath('1f363')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😘"><img class="emoji large" src="{$c->getSmileyPath('1f618')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😙"><img class="emoji large" src="{$c->getSmileyPath('1f619')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😚"><img class="emoji large" src="{$c->getSmileyPath('1f61a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😛"><img class="emoji large" src="{$c->getSmileyPath('1f61b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😜"><img class="emoji large" src="{$c->getSmileyPath('1f61c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😝"><img class="emoji large" src="{$c->getSmileyPath('1f61d')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🛀"><img alt=":bath:" class="emoji large" src="{$c->getSmileyPath('1f6c0')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎧"><img alt=":headphones:" class="emoji large" src="{$c->getSmileyPath('1f3a7')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎮"><img alt=":video_game:" class="emoji large" src="{$c->getSmileyPath('1f3ae')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎫"><img alt=":ticket:" class="emoji large" src="{$c->getSmileyPath('1f3ab')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="💼"><img alt=":briefcase:" class="emoji large" src="{$c->getSmileyPath('1f4bc')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎒"><img alt=":school_satchel:" class="emoji large" src="{$c->getSmileyPath('1f392')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😞"><img class="emoji large" src="{$c->getSmileyPath('1f61e')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😟"><img class="emoji large" src="{$c->getSmileyPath('1f61f')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😠"><img class="emoji large" src="{$c->getSmileyPath('1f620')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😡"><img class="emoji large" src="{$c->getSmileyPath('1f621')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😢"><img class="emoji large" src="{$c->getSmileyPath('1f622')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😣"><img class="emoji large" src="{$c->getSmileyPath('1f623')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="💡"><img alt=":bulb:" class="emoji large" src="{$c->getSmileyPath('1f4a1')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="📞"><img alt=":telephone_receiver:" class="emoji large" src="{$c->getSmileyPath('1f4de')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🔥"><img alt=":fire:" class="emoji large" src="{$c->getSmileyPath('1f525')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🕐"><img alt=":clock1:" class="emoji large" src="{$c->getSmileyPath('1f550')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="✉"><img alt=":email:" class="emoji large" src="{$c->getSmileyPath('2709')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="✏"><img alt=":pencil2:" class="emoji large" src="{$c->getSmileyPath('270f')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😤"><img class="emoji large" src="{$c->getSmileyPath('1f624')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😥"><img class="emoji large" src="{$c->getSmileyPath('1f625')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😦"><img class="emoji large" src="{$c->getSmileyPath('1f626')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😧"><img class="emoji large" src="{$c->getSmileyPath('1f627')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😨"><img class="emoji large" src="{$c->getSmileyPath('1f628')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😩"><img class="emoji large" src="{$c->getSmileyPath('1f629')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="💋"><img alt=":kiss:" class="emoji large" src="{$c->getSmileyPath('1f48b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="♥"><img alt=":hearts:" class="emoji large" src="{$c->getSmileyPath('2665')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="💊"><img alt=":pill:" class="emoji large" src="{$c->getSmileyPath('1f48a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="💩"><img alt=":hankey:" class="emoji large" src="{$c->getSmileyPath('1f4a9')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="☕"><img alt=":coffee:" class="emoji large" src="{$c->getSmileyPath('2615')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="⏰"><img alt=":alarm_clock:" class="emoji large" src="{$c->getSmileyPath('23f0')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😪"><img class="emoji large" src="{$c->getSmileyPath('1f62a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😫"><img class="emoji large" src="{$c->getSmileyPath('1f62b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😬"><img class="emoji large" src="{$c->getSmileyPath('1f62c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😭"><img class="emoji large" src="{$c->getSmileyPath('1f62d')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😮"><img class="emoji large" src="{$c->getSmileyPath('1f62e')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😯"><img class="emoji large" src="{$c->getSmileyPath('1f62f')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🐷"><img alt=":pig:" class="emoji large" src="{$c->getSmileyPath('1f437')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐵"><img alt=":monkey_face:" class="emoji large" src="{$c->getSmileyPath('1f435')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐶"><img alt=":dog:" class="emoji large" src="{$c->getSmileyPath('1f436')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐸"><img alt=":frog:" class="emoji large" src="{$c->getSmileyPath('1f438')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐹"><img alt=":hamster:" class="emoji large" src="{$c->getSmileyPath('1f439')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐻"><img alt=":bear:" class="emoji large" src="{$c->getSmileyPath('1f43b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😰"><img class="emoji large" src="{$c->getSmileyPath('1f630')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😱"><img class="emoji large" src="{$c->getSmileyPath('1f631')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😲"><img class="emoji large" src="{$c->getSmileyPath('1f632')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😳"><img class="emoji large" src="{$c->getSmileyPath('1f633')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😴"><img class="emoji large" src="{$c->getSmileyPath('1f634')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="😵"><img class="emoji large" src="{$c->getSmileyPath('1f635')}"></td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,94 @@
<section>
<ul class="tabs">
<li onclick="Stickers_ajaxShow('{$jid}')">
<a href="#"><img alt=":sticker:" class="emoji medium" src="{$icon}"></a>
</li>
<li onclick="Stickers_ajaxSmiley('{$jid}')">
<a href="#"><img alt=":smiley:" class="emoji medium" src="{$c->getSmileyPath('1f603')}"></a>
</li>
<li onclick="Stickers_ajaxSmileyTwo('{$jid}')" class="active">
<a href="#"><img alt=":smiley:" class="emoji medium" src="{$c->getSmileyPath('1f44d')}"></a>
</li>
</ul>
<table class="emojis">
<tbody>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="👊"><img class="emoji large" src="{$c->getSmileyPath('1f44a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="👋"><img class="emoji large" src="{$c->getSmileyPath('1f44b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="👌"><img class="emoji large" src="{$c->getSmileyPath('1f44c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="👍"><img class="emoji large" src="{$c->getSmileyPath('1f44d')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="👎"><img class="emoji large" src="{$c->getSmileyPath('1f44e')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="👏"><img class="emoji large" src="{$c->getSmileyPath('1f44f')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🍌"><img alt=":banana:" class="emoji large" src="{$c->getSmileyPath('1f34c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍎"><img alt=":apple:" class="emoji large" src="{$c->getSmileyPath('1f34e')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🌼"><img alt=":blossom:" class="emoji large" src="{$c->getSmileyPath('1f33c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🌵"><img alt=":cactus:" class="emoji large" src="{$c->getSmileyPath('1f335')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🌹"><img alt=":rose:" class="emoji large" src="{$c->getSmileyPath('1f339')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍄"><img alt=":mushroom:" class="emoji large" src="{$c->getSmileyPath('1f344')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🍦"><img class="emoji large" src="{$c->getSmileyPath('1f366')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍩"><img class="emoji large" src="{$c->getSmileyPath('1f369')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍪"><img class="emoji large" src="{$c->getSmileyPath('1f36a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍫"><img class="emoji large" src="{$c->getSmileyPath('1f36b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍰"><img class="emoji large" src="{$c->getSmileyPath('1f370')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍺"><img class="emoji large" src="{$c->getSmileyPath('1f37a')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🍔"><img alt=":hamburger:" class="emoji large" src="{$c->getSmileyPath('1f354')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍕"><img alt=":pizza:" class="emoji large" src="{$c->getSmileyPath('1f355')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍗"><img alt=":poultry_leg:" class="emoji large" src="{$c->getSmileyPath('1f357')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍚"><img alt=":rice:" class="emoji large" src="{$c->getSmileyPath('1f35a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍜"><img alt=":ramen:" class="emoji large" src="{$c->getSmileyPath('1f35c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🍣"><img alt=":sushi:" class="emoji large" src="{$c->getSmileyPath('1f363')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🛀"><img alt=":bath:" class="emoji large" src="{$c->getSmileyPath('1f6c0')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎧"><img alt=":headphones:" class="emoji large" src="{$c->getSmileyPath('1f3a7')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎮"><img alt=":video_game:" class="emoji large" src="{$c->getSmileyPath('1f3ae')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎫"><img alt=":ticket:" class="emoji large" src="{$c->getSmileyPath('1f3ab')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="💼"><img alt=":briefcase:" class="emoji large" src="{$c->getSmileyPath('1f4bc')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🎒"><img alt=":school_satchel:" class="emoji large" src="{$c->getSmileyPath('1f392')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="💡"><img alt=":bulb:" class="emoji large" src="{$c->getSmileyPath('1f4a1')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="📞"><img alt=":telephone_receiver:" class="emoji large" src="{$c->getSmileyPath('1f4de')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🔥"><img alt=":fire:" class="emoji large" src="{$c->getSmileyPath('1f525')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🕐"><img alt=":clock1:" class="emoji large" src="{$c->getSmileyPath('1f550')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="✉"><img alt=":email:" class="emoji large" src="{$c->getSmileyPath('2709')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="✏"><img alt=":pencil2:" class="emoji large" src="{$c->getSmileyPath('270f')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="💋"><img alt=":kiss:" class="emoji large" src="{$c->getSmileyPath('1f48b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="♥"><img alt=":hearts:" class="emoji large" src="{$c->getSmileyPath('2665')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="💊"><img alt=":pill:" class="emoji large" src="{$c->getSmileyPath('1f48a')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="💩"><img alt=":hankey:" class="emoji large" src="{$c->getSmileyPath('1f4a9')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="☕"><img alt=":coffee:" class="emoji large" src="{$c->getSmileyPath('2615')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="⏰"><img alt=":alarm_clock:" class="emoji large" src="{$c->getSmileyPath('23f0')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🚈"><img class="emoji large" src="{$c->getSmileyPath('1f688')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🚋"><img class="emoji large" src="{$c->getSmileyPath('1f68b')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🚌"><img class="emoji large" src="{$c->getSmileyPath('1f68c')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🚐"><img class="emoji large" src="{$c->getSmileyPath('1f690')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🚕"><img class="emoji large" src="{$c->getSmileyPath('1f695')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🚗"><img class="emoji large" src="{$c->getSmileyPath('1f697')}"></td>
</tr>
<tr class="active">
<td onclick="Stickers.addSmiley(this);" data-emoji="🐷"><img alt=":pig:" class="emoji large" src="{$c->getSmileyPath('1f437')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐵"><img alt=":monkey_face:" class="emoji large" src="{$c->getSmileyPath('1f435')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐶"><img alt=":dog:" class="emoji large" src="{$c->getSmileyPath('1f436')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐸"><img alt=":frog:" class="emoji large" src="{$c->getSmileyPath('1f438')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐹"><img alt=":hamster:" class="emoji large" src="{$c->getSmileyPath('1f439')}"></td>
<td onclick="Stickers.addSmiley(this);" data-emoji="🐻"><img alt=":bear:" class="emoji large" src="{$c->getSmileyPath('1f43b')}"></td>
</tr>
</tbody>
</table>
</section>
<div>
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>
</div>

View file

@ -5,18 +5,19 @@
*
* @file Vcard4.php
* This file is part of MOVIM.
*
*
* @brief A widget which display all the infos of a contact, vcard 4 version
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
* Copyright (C)2013 MOVIM project
*
*
* See COPYING for licensing information.
*/
use Moxl\Xec\Action\Vcard4\Get;
use Moxl\Xec\Action\Vcard4\Set;
use Moxl\Xec\Action\Nickname\Set as Nickname;
use Respect\Validation\Validator;
@ -34,14 +35,14 @@ class Vcard4 extends \Movim\Widget\Base
$me = $cd->get();
$this->view->assign('getvcard', $this->call('ajaxGetVcard'));
if($me == null) {
$this->view->assign('form', $this->prepareForm(new \modl\Contact()));
} else {
$this->view->assign('form', $this->prepareForm($me));
}
}
function prepareForm($me) {
$vcardform = $this->tpl();
@ -50,12 +51,12 @@ class Vcard4 extends \Movim\Widget\Base
$vcardform->assign('gender', getGender());
$vcardform->assign('marital', getMarital());
$vcardform->assign('countries',getCountries());
$vcardform->assign(
'submit',
$this->call('ajaxVcardSubmit', "movim_form_to_json('vcard4')")
);
$vcardform->assign(
'privacy',
$this->call('ajaxChangePrivacy', "this.checked")
@ -78,7 +79,7 @@ class Vcard4 extends \Movim\Widget\Base
$j = (string)$i;
}
$m = getMonths();
$months[$j] = $m[$i];
}
for($i=date('o'); $i>= 1920; $i--) { array_push($years, $i); }
@ -86,16 +87,16 @@ class Vcard4 extends \Movim\Widget\Base
$vcardform->assign('days', $days);
$vcardform->assign('months', $months);
$vcardform->assign('years', $years);
return $vcardform->draw('_vcard4_form', true);
}
function onMyVcard4($packet) {
$c = $packet->content;
$html = $this->prepareForm($c);
Notification::append(null, $this->__('vcard.updated'));
RPC::call('movim_fill', 'vcard_form', $html);
RPC::commit();
}
@ -105,12 +106,12 @@ class Vcard4 extends \Movim\Widget\Base
Notification::append(null, $this->__('vcard.updated'));
RPC::commit();
}
function onMyVcard4NotReceived() {
Notification::append(null, $this->__('vcard.not_updated'));
RPC::commit();
}
function ajaxGetVcard() {
$r = new Get;
$r->setTo($this->user->getLogin())
@ -120,14 +121,14 @@ class Vcard4 extends \Movim\Widget\Base
function ajaxVcardSubmit($vcard) {
# Format it ISO 8601:
if($vcard->year->value != -1
&& $vcard->month->value != -1
if($vcard->year->value != -1
&& $vcard->month->value != -1
&& $vcard->day->value != -1)
$vcard->date->value =
$vcard->date->value =
$vcard->year->value.'-'.
$vcard->month->value.'-'.
$vcard->day->value;
unset($vcard->year->value);
unset($vcard->month->value);
unset($vcard->day->value);
@ -137,15 +138,20 @@ class Vcard4 extends \Movim\Widget\Base
if($c == null)
$c = new \Modl\Contact();
$c->jid = $this->user->getLogin();
if(isset($vcard->date->value)) {
$c->date = $vcard->date->value;
}
}
if(Validator::stringType()->length(0, 40)->validate($vcard->name->value))
if(Validator::stringType()->length(0, 40)->validate($vcard->name->value)) {
$c->name = $vcard->name->value;
$n = new Nickname;
$n->setNickname($c->name)
->request();
}
if(Validator::stringType()->length(0, 40)->validate($vcard->fn->value))
$c->fn = $vcard->fn->value;
@ -169,10 +175,10 @@ class Vcard4 extends \Movim\Widget\Base
if(Validator::stringType()->validate($vcard->desc->value))
$c->description = trim($vcard->desc->value);
$cd = new \Modl\ContactDAO();
$cd->set($c);
$r = new Set;
$r->setData($c)->request();

View file

@ -39,7 +39,7 @@
</div>
<div class="block">
<input type="text" name="name" class="content" value="{$me->name}" placeholder="{$c->__('general.nickname')}">
<label for="fn">{$c->__('general.nickname')}</label>
<label for="name">{$c->__('general.nickname')}</label>
</div>
<div class="block large">
@ -54,7 +54,7 @@
<div class="select" style="width: 33.33%; float: left;">
<select name="day" class="datepicker">
<option value="-1">{$c->__('Day')}</option>
<option value="-1">{$c->__('day.title')}</option>
{loop="$days"}
<option value="{$value}"
{if="$key == substr($me->date, 8)"}
@ -66,7 +66,7 @@
</div>
<div class="select" style="width: 33.33%; float: right;">
<select name="year" class="datepicker">
<option value="-1">{$c->__('Year')}</option>
<option value="-1">{$c->__('year.title')}</option>
{loop="$years"}
<option value="{$value}"
{if="$value == substr($me->date,0,4)"}
@ -78,7 +78,7 @@
</div>
<div class="select" style="width: 33.33%;">
<select name="month" class="datepicker">
<option value="-1">{$c->__('Month')}</option>
<option value="-1">{$c->__('month.title')}</option>
{loop="$months"}
<option value="{$key}"
{if="$key == substr($me->date,5,2)"}
@ -91,7 +91,6 @@
</div>
<div class="block">
<label for="gender">{$c->__('general.gender')}</label>
<div class="select">
<select name="gender">
{loop="$gender"}
@ -103,6 +102,7 @@
{/loop}
</select>
</div>
<label for="gender">{$c->__('general.gender')}</label>
</div>
<div class="block">

View file

@ -34,6 +34,7 @@
"respect/validation": "1.0.*",
"ezyang/htmlpurifier": "^4.7",
"ramsey/uuid": "^3.2",
"symfony/console": "^3.0"
"symfony/console": "^3.0",
"cocur/slugify": "^2.1"
}
}

167
sources/composer.lock generated
View file

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "03f969c6eb107a15b0b5239da2d3c76e",
"content-hash": "bfebdd8e42854b5a00c9d5dc776a6212",
"hash": "e914006b3e14705d83af8c2166731383",
"content-hash": "de59bc3d1dbeb01e0e15e0347a1cd25e",
"packages": [
{
"name": "cboden/ratchet",
@ -55,18 +55,81 @@
],
"time": "2015-12-23 15:06:48"
},
{
"name": "cocur/slugify",
"version": "v2.1.1",
"source": {
"type": "git",
"url": "https://github.com/cocur/slugify.git",
"reference": "eee9879958875921082293dbdbf4866b641864f2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cocur/slugify/zipball/eee9879958875921082293dbdbf4866b641864f2",
"reference": "eee9879958875921082293dbdbf4866b641864f2",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"require-dev": {
"laravel/framework": "~5.1",
"latte/latte": "~2.2",
"mikey179/vfsstream": "~1.6",
"mockery/mockery": "~0.9",
"nette/di": "~2.2",
"phpunit/phpunit": "~4.8|~5.2",
"pimple/pimple": "~1.1",
"plumphp/plum": "~0.1",
"silex/silex": "~1.3",
"symfony/config": "~2.4|~3.0",
"symfony/dependency-injection": "~2.4|~3.0",
"symfony/http-kernel": "~2.4|~3.0",
"twig/twig": "~1.12",
"zendframework/zend-modulemanager": "~2.2",
"zendframework/zend-servicemanager": "~2.2",
"zendframework/zend-view": "~2.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Cocur\\Slugify\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ivo Bathke",
"email": "ivo.bathke@gmail.com"
},
{
"name": "Florian Eckerstorfer",
"email": "florian@eckerstorfer.co",
"homepage": "https://florian.ec"
}
],
"description": "Converts a string into a slug.",
"keywords": [
"slug",
"slugify"
],
"time": "2016-04-08 18:57:21"
},
{
"name": "embed/embed",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/oscarotero/Embed.git",
"reference": "6e6c07b2ec0424d1850c7ebeb4580307b83a9b9e"
"reference": "a76bf06a3941315f1dda96e3bcca85e760792875"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/oscarotero/Embed/zipball/6e6c07b2ec0424d1850c7ebeb4580307b83a9b9e",
"reference": "6e6c07b2ec0424d1850c7ebeb4580307b83a9b9e",
"url": "https://api.github.com/repos/oscarotero/Embed/zipball/a76bf06a3941315f1dda96e3bcca85e760792875",
"reference": "a76bf06a3941315f1dda96e3bcca85e760792875",
"shasum": ""
},
"require": {
@ -107,7 +170,7 @@
"opengraph",
"twitter cards"
],
"time": "2016-03-25 09:40:48"
"time": "2016-05-09 14:46:41"
},
{
"name": "evenement/evenement",
@ -705,12 +768,12 @@
"source": {
"type": "git",
"url": "https://github.com/movim/moxl.git",
"reference": "497a2111872660f3ebbeb1ad71ec8425c0be9d43"
"reference": "25cc10feda6eedcdf9b42546f5101f5c9f6a0655"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/movim/moxl/zipball/497a2111872660f3ebbeb1ad71ec8425c0be9d43",
"reference": "497a2111872660f3ebbeb1ad71ec8425c0be9d43",
"url": "https://api.github.com/repos/movim/moxl/zipball/25cc10feda6eedcdf9b42546f5101f5c9f6a0655",
"reference": "25cc10feda6eedcdf9b42546f5101f5c9f6a0655",
"shasum": ""
},
"require": {
@ -745,7 +808,7 @@
"php",
"xmpp"
],
"time": "2016-04-10 08:19:13"
"time": "2016-05-10 22:04:45"
},
{
"name": "movim/sasl2",
@ -1021,16 +1084,16 @@
},
{
"name": "ramsey/uuid",
"version": "3.3.0",
"version": "3.4.1",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
"reference": "f44f53e5ceb7474a83b6e11e6623ff9d6f6da598"
"reference": "b4fe3b7387cb323fd15ad5837cae992422c9fa5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/f44f53e5ceb7474a83b6e11e6623ff9d6f6da598",
"reference": "f44f53e5ceb7474a83b6e11e6623ff9d6f6da598",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/b4fe3b7387cb323fd15ad5837cae992422c9fa5c",
"reference": "b4fe3b7387cb323fd15ad5837cae992422c9fa5c",
"shasum": ""
},
"require": {
@ -1042,6 +1105,8 @@
},
"require-dev": {
"apigen/apigen": "^4.1",
"codeception/aspect-mock": "1.0.0",
"goaop/framework": "1.0.0-alpha.2",
"ircmaxell/random-lib": "^1.1",
"jakub-onderka/php-parallel-lint": "^0.9.0",
"mockery/mockery": "^0.9.4",
@ -1095,7 +1160,7 @@
"identifier",
"uuid"
],
"time": "2016-03-22 18:40:53"
"time": "2016-04-24 00:30:41"
},
{
"name": "react/cache",
@ -1305,16 +1370,16 @@
},
{
"name": "react/promise",
"version": "v2.4.0",
"version": "v2.4.1",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "f942da7b505d1a294284ab343d05df42d02ad6d9"
"reference": "8025426794f1944de806618671d4fa476dc7626f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/f942da7b505d1a294284ab343d05df42d02ad6d9",
"reference": "f942da7b505d1a294284ab343d05df42d02ad6d9",
"url": "https://api.github.com/repos/reactphp/promise/zipball/8025426794f1944de806618671d4fa476dc7626f",
"reference": "8025426794f1944de806618671d4fa476dc7626f",
"shasum": ""
},
"require": {
@ -1345,7 +1410,7 @@
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"time": "2016-03-31 13:10:33"
"time": "2016-05-03 17:50:52"
},
{
"name": "react/promise-timer",
@ -1528,16 +1593,16 @@
},
{
"name": "respect/validation",
"version": "1.0.5",
"version": "1.0.7",
"source": {
"type": "git",
"url": "https://github.com/Respect/Validation.git",
"reference": "294368294f9cd207f81474bab27d99875a19ac55"
"reference": "6597aa51149aff674faa9db1729c0c70392aa296"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Respect/Validation/zipball/294368294f9cd207f81474bab27d99875a19ac55",
"reference": "294368294f9cd207f81474bab27d99875a19ac55",
"url": "https://api.github.com/repos/Respect/Validation/zipball/6597aa51149aff674faa9db1729c0c70392aa296",
"reference": "6597aa51149aff674faa9db1729c0c70392aa296",
"shasum": ""
},
"require": {
@ -1588,7 +1653,7 @@
"validation",
"validator"
],
"time": "2016-03-31 17:39:15"
"time": "2016-05-07 18:51:56"
},
{
"name": "stojg/crop",
@ -1638,16 +1703,16 @@
},
{
"name": "symfony/console",
"version": "v3.0.4",
"version": "v3.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "6b1175135bc2a74c08a28d89761272de8beed8cd"
"reference": "34a214710e0714b6efcf40ba3cd1e31373a97820"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/6b1175135bc2a74c08a28d89761272de8beed8cd",
"reference": "6b1175135bc2a74c08a28d89761272de8beed8cd",
"url": "https://api.github.com/repos/symfony/console/zipball/34a214710e0714b6efcf40ba3cd1e31373a97820",
"reference": "34a214710e0714b6efcf40ba3cd1e31373a97820",
"shasum": ""
},
"require": {
@ -1694,20 +1759,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2016-03-16 17:00:50"
"time": "2016-04-28 09:48:42"
},
{
"name": "symfony/event-dispatcher",
"version": "v3.0.4",
"version": "v3.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "9002dcf018d884d294b1ef20a6f968efc1128f39"
"reference": "807dde98589f9b2b00624dca326740380d78dbbc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9002dcf018d884d294b1ef20a6f968efc1128f39",
"reference": "9002dcf018d884d294b1ef20a6f968efc1128f39",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/807dde98589f9b2b00624dca326740380d78dbbc",
"reference": "807dde98589f9b2b00624dca326740380d78dbbc",
"shasum": ""
},
"require": {
@ -1754,20 +1819,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2016-03-10 10:34:12"
"time": "2016-05-05 06:56:13"
},
{
"name": "symfony/http-foundation",
"version": "v3.0.4",
"version": "v3.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "99f38445a874e7becb8afc4b4a79ee181cf6ec3f"
"reference": "18b24bc32d2495ae79d76e777368786a6536fe31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/99f38445a874e7becb8afc4b4a79ee181cf6ec3f",
"reference": "99f38445a874e7becb8afc4b4a79ee181cf6ec3f",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/18b24bc32d2495ae79d76e777368786a6536fe31",
"reference": "18b24bc32d2495ae79d76e777368786a6536fe31",
"shasum": ""
},
"require": {
@ -1807,20 +1872,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2016-03-27 14:50:32"
"time": "2016-04-12 18:09:53"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.1.1",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "1289d16209491b584839022f29257ad859b8532d"
"reference": "dff51f72b0706335131b00a7f49606168c582594"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d",
"reference": "1289d16209491b584839022f29257ad859b8532d",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
"reference": "dff51f72b0706335131b00a7f49606168c582594",
"shasum": ""
},
"require": {
@ -1832,7 +1897,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
"dev-master": "1.2-dev"
}
},
"autoload": {
@ -1866,20 +1931,20 @@
"portable",
"shim"
],
"time": "2016-01-20 09:13:37"
"time": "2016-05-18 14:26:46"
},
{
"name": "symfony/routing",
"version": "v3.0.4",
"version": "v3.0.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "d061b609f2d0769494c381ec92f5c5cc5e4a20aa"
"reference": "a6cd168310066176599442aa21f5da86c3f8e0b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/d061b609f2d0769494c381ec92f5c5cc5e4a20aa",
"reference": "d061b609f2d0769494c381ec92f5c5cc5e4a20aa",
"url": "https://api.github.com/repos/symfony/routing/zipball/a6cd168310066176599442aa21f5da86c3f8e0b3",
"reference": "a6cd168310066176599442aa21f5da86c3f8e0b3",
"shasum": ""
},
"require": {
@ -1941,7 +2006,7 @@
"uri",
"url"
],
"time": "2016-03-23 13:23:25"
"time": "2016-05-03 12:23:49"
}
],
"packages-dev": [],

View file

@ -64,6 +64,7 @@ accept = Accept
refuse = Refuse
next = Next
previous = Previous
search = Search
[input]
username = Username

View file

@ -12,11 +12,11 @@
.flex.card .block.large {
flex: 1 100%;
}
/*
.flex.card {
padding: 0;
}
*/
.flex.card .block {
margin: 1rem;
flex: 1 calc(50% - 2rem);

View file

@ -0,0 +1,24 @@
/* Card */
/*
.card {
padding: 1rem;
}
*/
.card > .block:not(.subheader) {
background-color: white;
border-radius: 2px;
border: 1px solid rgba(0, 0, 0, 0.12);
overflow: hidden;
margin-bottom: 1rem;
}
.card > form.block {
padding: 2rem;
padding-top: 0;
box-sizing: border-box;
}
.card.shadow > .block:not(.subheader) {
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.12), 0px 1px 2px rgba(0, 0, 0, 0.24);
border: none;
}

View file

@ -56,10 +56,12 @@ ul li.action > form > div.action,
.icon.gray , p.user.gray { color: #9E9E9E; }
.icon.black , p.user.black { color: #000; }
form input:focus:invalid,
form textarea:focus:invalid {
border-bottom-color: #F44336;
form > div > input:focus:invalid,
form > div > input:focus:required {
box-shadow: 0px 2px 0px #F44336;
}
form > div > input:invalid,
form input:focus:invalid + label,
form textarea:focus:invalid + label {
color: #F44336;
@ -125,7 +127,8 @@ form textarea:focus:not(:invalid) + label {
color: #FF5722;
}
form input:focus:not(:invalid),
form textarea:focus:not(:invalid) {
border-bottom-color: #FF5722;
form input:focus:not(:invalid):not(.button),
form textarea:focus:not(:invalid):not(.button) {
box-shadow:0px 2px 0px #FF5722;
}

View file

@ -0,0 +1,64 @@
/* Dialog */
.dialog {
position: fixed;
top: 5%;
left: 50%;
background-color: white;
height: initial;
max-height: 90%;
width: 50rem;
margin-left: -25rem;
overflow: hidden;
box-shadow: 0 2.5rem 5rem rgba(0,0,0,0.30), 0 2rem 1.5rem rgba(0,0,0,0.22);
border-radius: 0.25rem;
z-index: 3;
box-sizing: border-box;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.dialog:empty {
display: none;
}
.dialog.scroll {
height: 90%;
}
.dialog > section {
height: 100%;
overflow-y: auto;
position: relative;
}
.dialog > section > *:first-child:not(ul) {
margin-top: 2rem;
}
.dialog > section > *:last-child {
margin-bottom: 2rem;
}
.dialog > section > *:not(ul) {
padding: 0 2rem;
}
.dialog > section > form > ul > li {
padding: 0;
}
@media screen and (max-width: 600px) {
.dialog {
width: 90%;
height: 90%;
min-height: 0;
min-width: 0;
max-height: 90%;
margin-left: -45%;
margin-top: 0;
top: 5%;
}
}

View file

@ -30,10 +30,10 @@
}
.emoji {
width: 2rem;
height: 2rem;
width: 3rem;
height: 3rem;
margin: 0 0.5rem;
margin-bottom: -0.3rem;
margin-bottom: -0.7rem;
}
.emoji.medium {

View file

@ -1,7 +1,7 @@
/* Form */
form > div:not(.clear):not(.control) {
min-height: 9.5rem;
min-height: 9rem;
position: relative;
box-sizing: border-box;
}
@ -12,7 +12,6 @@ form > div.compact:not(.clear):not(.control) {
li > form > div:not(.control) { /* If we put the form in a list */
min-height: 0;
line-height: 3rem;
padding-top: 0rem;
top: -1.5rem;
}
@ -30,12 +29,7 @@ form > div > label {
form > div.icon {
padding-left: 9rem;
}
/*
form > div > input:focus + label,
form > div > textarea:focus + label {
display: block;
}
*/
form > div > textarea,
#hiddendiv {
border: none;
@ -45,26 +39,30 @@ form > div > textarea,
box-sizing: border-box;
}
form > div > .select {
position: relative;
}
form > div > .select:after {
font-family: "Material-Design-Iconic-Font";
content: "\f2f2";
display: block;
font-size: 4rem;
color: #B8B8B8;
color: #999;
position: absolute;
right: 1.25rem;
bottom: 0.25rem;
pointer-events: none;
}
form > div > .select:hover:after {
color: #555;
}
form > div > .select select {
width: calc(100% + 3rem);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: 100%;
background-color: transparent;
background-image: none;
padding: 1rem 0;
}
main > header form > div:not(.clear):not(.control) {
@ -92,26 +90,39 @@ main > header form > div:not(.clear):not(.control) > .select select {
}
/* Placeholders to mimic FF */
::-webkit-input-placeholder, /* WebKit browsers */
:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #fff;
color: #fff;
opacity: 0.5;
}
/* Webkit weird CSS, sic */
form > div > .select select,
form > div > input:not([type=submit]),
form > div > textarea {
outline-width: 0;
}
form > div > .select,
form > div > input:not([type=submit]),
form > div > textarea {
display: block;
padding: 1rem 0;
padding-top: 5rem;
padding-top: 4.5rem;
width: 100%;
background-color: transparent;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
margin-bottom: 1rem;
overflow: hidden; /* Fixme */
box-shadow:0px 1px 0px rgba(0, 0, 0, 0.12);
}
box-shadow: none; /* Firefox weird CSS */
form > div > .select {
position: relative;
padding-top: 4rem;
padding-bottom: 0;
}
form > div.compact > .select,
@ -125,21 +136,10 @@ form > div > input:not([type=submit]):-webkit-autofill {
-webkit-box-shadow: 0 0 0 50px white inset;
}
form > div > input:not([type=submit]):-webkit-autofill:focus {
-webkit-box-shadow: 0;
box-shadow: 0;
-webkit-text-fill-color: #333;
}
form > div > input:focus,
form > div > textarea:focus {
border-bottom-width: 2px;
margin-bottom: calc(1rem - 1px);
}
form > div > input:invalid,
form > div > input:required {
box-shadow: none;
}
/* Checkbox element */
form > div .checkbox > input[type="checkbox"],
@ -247,6 +247,7 @@ form > div > input:disabled + label {
float: right;
}
.button:disabled,
.button.inactive {
opacity: 0.5;
pointer-events:none;
@ -358,7 +359,7 @@ header.big ~ .button.action {
@media screen and (min-width: 1025px) {
main > section > div:first-child:nth-last-child(2) .button.action {
right: calc(65% + 3rem);
right: calc(70% + 3rem);
}
}
@ -367,6 +368,7 @@ header.big ~ .button.action {
bottom: 7rem;
left: 0;
padding: 0;
pointer-events: none;
}
.button.action .actions li {
@ -383,6 +385,10 @@ header.big ~ .button.action {
pointer-events: none;
}
.button.action.active .actions {
pointer-events: auto;
}
.button.action.active .actions li {
opacity: 1;
pointer-events: auto;
@ -413,3 +419,4 @@ header.big ~ .button.action {
word-wrap: break-word;
overflow-wrap: break-word; /* future version of deprecated 'word-wrap' */
}

View file

@ -9,21 +9,21 @@ header.big {
margin-bottom: 2rem;
}
header.fixed {
position: fixed;
width: 100%;
max-width: 100%;
z-index: 1;
top: 0;
}
@media screen and (min-width: 1024px) {
main > section > div:first-child:nth-last-child(2) ~ div > header.fixed {
width: 65%;
width: inherit;
}
}
header.fixed + div {
header.fixed:not(:empty) + * {
margin-top: 7rem;
}

View file

@ -0,0 +1,82 @@
/* Icon */
span.icon {
font-size: 3rem;
line-height: 5rem;
text-align: center;
background-size: cover;
background-position: center;
}
span.icon img {
max-width: 100%;
max-height: 100%;
}
span.icon.primary.thumb {
left: 0;
width: 7rem;
top: 0;
height: 100%;
margin: 0;
line-height: 7.5rem;
}
li.oppose span.icon {
left: auto;
right: 2rem;
}
span.icon.bubble {
border-radius: 5rem;
color: white;
font-size: 0;
font-size: 2.5rem;
}
span.icon.bubble img {
border-radius: 5rem;
}
span.icon.bubble i {
font-size: 3rem;
line-height: 5rem;
}
ul.list li span.icon.small {
width: 3rem;
height: 3rem;
line-height: 3rem;
margin-top: -1.5rem;
}
/*ul.list li > .control.small,
ul.list li > .primary.small {
width: 3rem;
height: 3rem;
line-height: 3rem;
}*/
span.icon.small.bubble:first-letter,
span.icon.small.bubble i {
font-size: 2rem;
line-height: 1.5em;
vertical-align: text-top;
}
span.icon.status:after {
content: '';
display: block;
width: 2rem;
height: 2rem;
left: 3.25rem;
top: 3.25rem;
position: absolute;
border-radius: 2em;
background-color: #DDD;
}
main ul li .control > i {
margin-left: 0;
}

View file

@ -3,6 +3,10 @@ ul.list {
padding: 0;
}
ul.list li:not(.subheader) {
padding: 0.25rem 0;
}
ul.list.middle li:not(.subheader) {
padding: 0.75rem 0;
}
@ -23,7 +27,6 @@ ul.list li > *:not(p) {
/* Active list */
ul.list.active li:hover:not(.subheader),
ul.list.active.all li:hover,
ul.list.active li.active:not(.subheader) {
@ -33,31 +36,32 @@ ul.list.active li.active:not(.subheader) {
/* Main elements */
ul.list li > .control,
ul.list li > .primary {
ul.list li .control,
ul.list li .primary {
width: 5rem;
height: 5rem;
top: 50%;
margin-top: -2.5rem;
position: absolute;
line-height: 5rem;
}
ul.list li > .control.active,
ul.list li > .primary.active {
width: 7rem;
height: 7rem;
ul.list li .control:not(.bubble):not(.thumb),
ul.list li .primary:not(.bubble):not(.thumb) {
margin-top: -3rem;
padding: 0.5rem;
}
ul.list.middle li .control:not(.bubble):not(.thumb),
ul.list.middle li .primary:not(.bubble):not(.thumb) {
margin-top: -3.5rem;
line-height: 7rem;
padding: 1rem 0.5rem;
}
ul.list li > .primary.active {
left: 0;
}
ul.list li > .control.small,
ul.list li > .primary.small {
width: 3rem;
height: 3rem;
margin-top: -1.5rem;
ul.list.thick li .control:not(.bubble):not(.thumb),
ul.list.thick li .primary:not(.bubble):not(.thumb) {
margin-top: -4.25rem;
padding: 1.75rem 0.5rem;
}
ul.list > li > *:not(img):not(.counter):not(span):not(.bubble):not(.button),
@ -151,8 +155,11 @@ ul.list li.subheader > p {
/* If we have a primary control */
ul.list li > .primary {
left: 1.5rem;
}
ul.list li > .primary.bubble {
left: 2rem;
}
@ -167,39 +174,37 @@ ul.list li > .control {
}
ul.list li > .control ~ .control {
right: 5rem;
right: 6rem;
}
ul.list li > .control ~ .control ~ .control {
right: 10rem;
right: 12rem;
}
/* Limit the size of the main content */
ul.list li > .control ~ *:not(.control):not(.bubble):not(.counter) {
width: calc(100% - 5rem);
width: calc(100% - 6rem);
}
ul.list li > .control ~ .control ~ *:not(.control):not(.bubble):not(.counter) {
width: calc(100% - 10rem);
width: calc(100% - 12rem);
}
ul.list li > .control ~ .control ~ .control ~ *:not(.control):not(.bubble):not(.counter) {
width: calc(100% - 15rem);
}
/* Place the other controls */
header > ul.list li > .control ~ .control {
right: 7rem;
}
header > ul.list li > .control ~ .control ~ .control {
right: 14rem;
width: calc(100% - 18rem);
}
/* Limit the size of the main content */
header > ul.list li .primary {
left: 0;
}
header > ul.list li > .primary ~ :not(.primary):not(.counter):not(.bubble):not(.control) {
padding-left: 9rem;
}
/*
header > ul.list li > .control ~ *:not(.control):not(.bubble):not(.counter) {
width: calc(100% - 7rem);
}
@ -211,7 +216,7 @@ header > ul.list li > .control ~ .control ~ *:not(.control):not(.bubble):not(.co
header > ul.list li > .control ~ .control ~ .control ~ *:not(.control):not(.bubble):not(.counter) {
width: calc(100% - 21rem);
}
*/
/* Tabs */
ul.tabs {
@ -388,3 +393,21 @@ ul.context_menu.shown {
display: block;
}
/* Divided */
*.divided:not(.spaced) > *:not(:last-child),
*.divided.spaced > *:not(:last-child).subheader,
*.divided.spaced > *:not(:last-child):not(.subheader):after {
border-bottom-width: 1px;
border-bottom-style: solid;
}
*.divided.spaced > *:not(:last-child):after {
position: absolute;
right: 0;
bottom: 0rem;
content: "";
display: block;
width: calc(100% - 9rem);
}

View file

@ -1,13 +1,21 @@
/* Menu */
body > nav > ul.list li > .primary {
left: 1rem;
}
body > nav > ul:nth-child(2) li p.normal,
body > nav > ul:nth-child(3) li p.normal {
height: 6rem;
line-height: 6rem;
line-height: 6.25rem;
}
body > nav > ul.list li > .primary ~ :not(.primary):not(.counter):not(.bubble):not(.control) {
padding-left: 7rem;
}
body > nav > ul.list li > .primary {
left: 0.5rem;
}
body > nav > ul.list li > .primary.bubble {
left: 1rem;
}
body > nav > ul a {

View file

@ -74,7 +74,8 @@ h1 { /* Display 1 */
h2 { /* Headline */
font-size: 3rem;
line-height: 7rem;
line-height: 4rem;
padding: 2rem 0;
}
h2.thin {
@ -181,6 +182,14 @@ body > nav li { /* Little hack for the navbar */
}
}
body > nav li span.counter {
left: 3.5rem;
top: calc(50% - 1.25rem);
right: auto;
font-size: 1.75rem;
padding: 0.25rem;
}
/*
@media screen and (min-width: 1024px) and (max-width: 1679px) {
body > nav p {
transition: opacity 0.5s cubic-bezier(.4,0,.2,1);
@ -209,7 +218,7 @@ body > nav li { /* Little hack for the navbar */
padding: 0.25rem;
}
}
*/
@media screen and (min-width: 1680px) {
body > nav,
body > nav:hover {
@ -223,7 +232,7 @@ body > nav li { /* Little hack for the navbar */
}
body > nav.active:before,
body > nav:hover:before {
/*body > nav:hover:before*/ {
display: none;
}
@ -256,13 +265,13 @@ main > header {
main > header > div {
position: relative;
width: 35%;
width: 30%;
display: inline-block;
box-sizing: border-box;
}
main > header > div:first-child:nth-last-child(2) ~ div {
width: 65%;
width: 70%;
position: absolute;
top: 0;
right: 0;
@ -308,10 +317,10 @@ main > section > div > * {
/* Two blocks*/
main > section > div:first-child:nth-last-child(2) {
width: 35%;
width: 30%;
}
main > section > div:first-child:nth-last-child(2) ~ div {
width: 65%;
width: 70%;
position: absolute;
top: 0;
right: 0;
@ -366,189 +375,6 @@ main footer {
font-size: 2rem;
}
/* Icon */
span.icon {
/*width: 5rem;
height: 5rem;
position: absolute;*/
font-size: 3rem;
line-height: 5rem;
/*top: 50%;
left: 2rem;*/
text-align: center;
/*margin-top: -2.5rem;*/
background-size: cover;
background-position: center;
}
span.icon img {
max-width: 100%;
max-height: 100%;
}
span.icon.primary.thumb {
left: 0;
width: 7rem;
top: 0;
height: 100%;
margin: 0;
line-height: 7.5rem;
}
li.oppose span.icon {
left: auto;
right: 2rem;
}
span.icon.bubble {
border-radius: 5rem;
color: white;
font-size: 0;
font-size: 2.5rem;
}
span.icon.bubble img {
border-radius: 5rem;
}
span.icon.bubble i {
font-size: 3rem;
line-height: 5rem;
}
span.icon.small {
width: 3rem;
height: 3rem;
line-height: 3rem;
margin-top: -1.5rem;
}
/*
span.icon.tiny {
font-size: 1.8rem;
font-weight: 600;
}
span.icon.large {
width: 7rem;
height: 7rem;
line-height: 7rem;
margin-top: -3.5rem;
}
*/
span.icon.small.bubble:first-letter,
span.icon.small.bubble i {
font-size: 2rem;
line-height: 1.5em;
vertical-align: text-top;
}
span.icon.status:after {
content: '';
display: block;
width: 2rem;
height: 2rem;
left: 3.25rem;
top: 3.25rem;
position: absolute;
border-radius: 2em;
background-color: #DDD;
}
main ul li .control > i {
margin-left: 0;
}
/* Card */
.card {
padding: 1rem;
}
.card > .block:not(.subheader) {
background-color: white;
border-radius: 2px;
border: 1px solid rgba(0, 0, 0, 0.12);
overflow: hidden;
margin-bottom: 1rem;
}
.card > form.block {
padding: 2rem;
padding-top: 0;
box-sizing: border-box;
}
.card.shadow > .block:not(.subheader) {
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.12), 0px 1px 2px rgba(0, 0, 0, 0.24);
border: none;
}
/* Dialog */
.dialog {
position: fixed;
top: 5%;
left: 50%;
background-color: white;
height: initial;
max-height: 90%;
width: 50rem;
margin-left: -25rem;
overflow: hidden;
box-shadow: 0 2.5rem 5rem rgba(0,0,0,0.30), 0 2rem 1.5rem rgba(0,0,0,0.22);
border-radius: 0.25rem;
z-index: 3;
box-sizing: border-box;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.dialog:empty {
display: none;
}
.dialog.scroll {
height: 90%;
}
.dialog > section {
height: 100%;
overflow-y: auto;
position: relative;
}
.dialog > section > *:first-child:not(ul) {
margin-top: 2rem;
}
.dialog > section > *:last-child {
margin-bottom: 2rem;
}
.dialog > section > *:not(ul) {
padding: 0 2rem;
}
.dialog > section > form > ul > li {
padding: 0;
}
@media screen and (max-width: 600px) {
.dialog {
width: 90%;
height: 90%;
min-height: 0;
min-width: 0;
max-height: 90%;
margin-left: -45%;
margin-top: 0;
top: 5%;
}
}
/* Actions bar */
.actions {
@ -722,6 +548,7 @@ main section > div:first-child:nth-last-child(2) ~ div .actions.fixed > div:last
.icon.pages { background-image: url(../img/icons/pages.svg); }
.icon.bookmark { background-image: url(../img/icons/bookmark.svg); }
.icon.clipboard { background-image: url(../img/icons/person.svg); }
.icon.search { background-image: url(../img/icons/search.svg); }
/* Definition list */
@ -775,25 +602,8 @@ dl dd {
}
}
/* Divided */
*.divided:not(.spaced) > *:not(:last-child),
*.divided.spaced > *:not(:last-child).subheader,
*.divided.spaced > *:not(:last-child):not(.subheader):after {
border-bottom-width: 1px;
border-bottom-style: solid;
}
*.divided.spaced > *:not(:last-child):after {
position: absolute;
right: 0;
bottom: 0rem;
content: "";
display: block;
width: calc(100% - 9rem);
}
/* Spinner */
.spinner {
position: relative;
}
@ -820,7 +630,7 @@ dl dd {
}
.spinner:before {
z-index: 2;
z-index: 3;
width: 3.5rem;
height: 3.5rem;
margin: 1rem;
@ -833,6 +643,8 @@ dl dd {
}
.spinner:after {
z-index: 2;
box-shadow: 0px 0.5rem 1.25rem rgba(0, 0, 0, 0.23), 0px 0.5rem 1.25rem rgba(0, 0, 0, 0.16);
background-color: white;
@ -869,12 +681,14 @@ dl dd {
}
/* Disabled */
.disabled {
opacity: 0.5;
pointer-events: none;
}
/* Spinner */
div#spinner{
position: relative;
overflow: visible;

View file

@ -0,0 +1,52 @@
table.table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1rem;
}
table.table tbody tr:hover {
background-color: #EEE;
}
table.table th,
table.table td {
text-align: right;
}
table.table th li,
table.table td li {
text-align: left;
}
table.table thead tr th,
table.table tr:not(:last-child) td {
border-bottom: 1px solid #CCC;
}
table.table th,
table.table td {
line-height: 6rem;
padding-left: 2rem;
padding-right: 5rem;
}
table.table th {
line-height: 7rem;
font-size: 1.8rem;
font-weight: bold;
}
table.table th:last-child,
table.table td:last-child {
padding-right: 2rem;
}
table.table td li i {
line-height: 7rem;
}
table.table th[colspan],
table.table td[colspan] {
padding: 0;
}

View file

@ -0,0 +1,55 @@
/* Titles */
h1 { /* Display 1 */
font-size: 4.25rem;
line-height: 7rem;
}
h2 { /* Headline */
font-size: 3rem;
line-height: 4rem;
padding: 2rem 0;
}
h2.thin {
line-height: 5rem;
}
h3 { /* Title */
font-size: 2.5rem;
font-weight: 700;
}
h4, input, textarea, select { /* Headline */
font-size: 2rem;
line-height: 2.5rem;
}
h4 {
font-weight: 400;
}
h4.gray {
color: rgba(0, 0, 0, 0.54);
}
article section content ul li, /* Body 1 */
article section content p {
font-size: 2rem;
font-weight: 300;
}
.snackbar, /* Body 2 */
.toast {
font-size: 1.75rem;
font-weight: 500;
}
label, span.info { /* Caption */
font-size: 1.5rem;
color: rgba(0, 0, 0, 0.54);
}
label, span.info b { /* Caption */
font-weight: 600;
}