Browse Source

- Continue the implementation of the Chat

- Fix the navigation panel (new organisation)
- Fix the Roster
- Contact edit and Contac delete
pull/16/head
Jaussoin Timothée 11 years ago
parent
commit
c725fd23ec
  1. 7
      app/assets/js/movim_tpl.js
  2. 2
      app/assets/js/movim_websocket.js
  3. 4
      app/views/chat.tpl
  4. 113
      app/widgets/Chat/Chat.php
  5. 67
      app/widgets/Chat/_chat.tpl
  6. 15
      app/widgets/Chat/_chat_header.tpl
  7. 21
      app/widgets/Chat/_chat_messages.tpl
  8. 26
      app/widgets/Chat/_chat_smiley.tpl
  9. 16
      app/widgets/Chat/chat.js
  10. 13
      app/widgets/Chat/locales.ini
  11. 12
      app/widgets/Chats/Chats.php
  12. 0
      app/widgets/Chats/_chats.tpl
  13. 0
      app/widgets/Chats/chats.tpl
  14. 2
      app/widgets/Contact/_contact_delete.tpl
  15. 4
      app/widgets/Contact/_contact_edit.tpl
  16. 2
      app/widgets/Contact/locales.ini
  17. 2
      app/widgets/Dialog/dialog.tpl
  18. 3
      app/widgets/Header/_header_chat.tpl
  19. 2
      app/widgets/Navigation/navigation.tpl
  20. 3
      app/widgets/Presence/_presence_list.tpl
  21. 4
      app/widgets/Roster/_roster_search.tpl
  22. 4
      themes/material/css/color.css
  23. 3
      themes/material/css/form.css
  24. 7
      themes/material/css/list.css
  25. 72
      themes/material/css/style.css

7
app/assets/js/movim_tpl.js

@ -61,6 +61,13 @@ var MovimTpl = {
movim_remove_class(selector, 'enabled');
},
scrollPanel : function() { // On for panel that are .contained
var selector = document.querySelector('main section > div:first-child:nth-last-child(2) ~ div div');
if(selector != null) {
selector.scrollTop = selector.scrollHeight;
}
},
showMenu : function() {
movim_add_class('body > nav', 'active');
}

2
app/assets/js/movim_websocket.js

@ -97,7 +97,7 @@ var MovimWebsocket = {
if(funcalls != null) {
for(h = 0; h < funcalls.length; h++) {
var funcall = funcalls[h];
//console.log(funcall);
console.log(funcall);
if(funcall.func != null && (typeof window[funcall.func] == 'function')) {
try {
window[funcall.func].apply(null, funcall.params);

4
app/views/chat.tpl

@ -7,8 +7,6 @@
<?php $this->widget('Header'); ?>
<section>
<?php $this->widget('Roster');?>
<div>
<?php $this->widget('Chat');?>
</div>
<?php $this->widget('Chat');?>
</section>
</main>

113
app/widgets/Chat/Chat.php

@ -1,11 +1,43 @@
<?php
use Moxl\Xec\Action\Message\Publish;
class Chat extends WidgetCommon
{
function load()
{
$this->addjs('chat.js');
$this->registerEvent('message', 'onMessage');
}
function onMessage($packet)
{
$message = $packet->content;
// If the message is from me
if($message->session == $message->jidto) {
$from = $message->jidfrom;
} else {
$from = $message->jidto;
}
RPC::call('movim_fill', $from.'_messages', $this->prepareMessages($from));
RPC::call('MovimTpl.scrollPanel');
}
/**
* @brief Show the smiley list
*/
function ajaxSmiley()
{
$view = $this->tpl();
Dialog::fill($view->draw('_chat_smiley', true));
}
/**
* @brief Get a discussion
* @parem string $jid
*/
function ajaxGet($jid)
{
$html = $this->prepareChat($jid);
@ -14,25 +46,102 @@ class Chat extends WidgetCommon
Header::fill($header);
RPC::call('movim_fill', 'chat_widget', $html);
RPC::call('MovimTpl.scrollPanel');
}
/**
* @brief Send a message
*
* @param string $to
* @param string $message
* @return void
*/
function ajaxSendMessage($to, $message, $muc = false, $ressource = false) {
if($message == '')
return;
$m = new \Modl\Message();
$m->session = $this->user->getLogin();
$m->jidto = echapJid($to);
$m->jidfrom = $this->user->getLogin();
$session = \Sessionx::start();
$m->type = 'chat';
$m->ressource = $session->ressource;
if($muc) {
$m->type = 'groupchat';
$m->ressource = $session->user;
$m->jidfrom = $to;
}
$m->body = rawurldecode($message);
$m->published = date('Y-m-d H:i:s');
$m->delivered = date('Y-m-d H:i:s');
$md = new \Modl\MessageDAO();
$md->set($m);
/* Is it really clean ? */
$packet = new Moxl\Xec\Payload\Packet;
$packet->content = $m;
$this->onMessage($packet, true);
if($ressource != false) {
$to = $to . '/' . $ressource;
}
// We decode URL codes to send the correct message to the XMPP server
$m = new Publish;
$m->setTo($to);
$m->setContent(htmlspecialchars(rawurldecode($message)));
/*if($muc) {
$m->setMuc();
}*/
$m->request();
}
function prepareHeader($jid)
{
$view = $this->tpl();
$cd = new \Modl\ContactDAO;
$view->assign('contact', $cd->get($jid));
$view->assign('jid', $jid);
return $view->draw('_chat_header', true);
}
function prepareChat($jid)
{
$view = $this->tpl();
$view->assign('jid', $jid);
$view->assign('messages', $this->prepareMessages($jid));
$view->assign(
'send',
$this->call(
'ajaxSendMessage',
"'" . $jid . "'",
"Chats.sendMessage(this, '" . $jid . "')")
);
$view->assign('smiley', $this->call('ajaxSmiley'));
return $view->draw('_chat', true);
}
function prepareMessages($jid)
{
$md = new \Modl\MessageDAO();
$messages = $md->getContact(echapJid($jid), 0, 10);
$messages = array_reverse($messages);
$cd = new \Modl\ContactDAO;
$view = $this->tpl();
$view->assign('jid', $jid);
@ -40,7 +149,7 @@ class Chat extends WidgetCommon
$view->assign('me', $cd->get());
$view->assign('messages', $messages);
return $view->draw('_chat', true);
return $view->draw('_chat_messages', true);
}
function display()

67
app/widgets/Chat/_chat.tpl

@ -1,17 +1,50 @@
<ul class="thick">
{loop="$messages"}
<li {if="$value->jidfrom == $jid"}class="oppose"{/if}>
<span class="icon bubble">
{if="$value->jidfrom == $jid"}
<img src="{$contact->getPhoto('s')}">
{else}
<img src="{$me->getPhoto('s')}">
{/if}
</span>
<div class="bubble">
{$value->body|prepareString}
<span class="info">{$value->delivered|strtotime|prepareDate}</span>
</div>
</li>
{/loop}
</ul>
<div id="{$jid}_discussion" class="actions fixed contained">
<div id="{$jid}_messages">
{$messages}
</div>
<div>
<ul>
<li>
<span class="icon gray">
<i class="md md-create"></i>
</span>
<div class="control" onclick="{$smiley}">
<i class="md md-mood"></i>
</div>
<form>
<div>
<textarea
rows="1"
id="textarea{$contact->jid}"
onkeypress="
if(event.keyCode == 13) {
state = 0;
{$send}
return false;
} else {
if(state == 0 || state == 2) {
state = 1;
{$composing}
since = new Date().getTime();
}
}
"
onkeyup="
movim_textarea_autoheight(this);
setTimeout(function()
{
if(state == 1 && since+5000 < new Date().getTime()) {
state = 2;
{$paused}
}
},5000);
"
placeholder="{$c->__('chat.placeholder')}"
></textarea>
<label>Your message</label>
</div>
</form>
</li>
</ul>
</div>
</div>

15
app/widgets/Chat/_chat_header.tpl

@ -2,15 +2,14 @@
<span class="on_desktop icon" onclick="MovimTpl.hidePanel()"><i class="md md-person"></i></span>
<ul class="active">
<li onclick="{$edit}">
<li onclick="{$close}">
<span class="icon">
<i class="md md-edit"></i>
</span>
</li>
<li onclick="{$delete}">
<span class="icon">
<i class="md md-delete"></i>
<i class="md md-close"></i>
</span>
</li>
</ul>
<h2>{$jid}</h2>
{if="$contact != null"}
<h2>{$contact->getTrueName()}</h2>
{else}
<h2>{$jid}</h2>
{/if}

21
app/widgets/Chat/_chat_messages.tpl

@ -0,0 +1,21 @@
<ul class="thick">
{loop="$messages"}
<li {if="$value->jidfrom == $jid"}class="oppose"{/if}>
<span class="icon bubble">
{if="$value->jidfrom == $jid"}
<img src="{$contact->getPhoto('s')}">
{else}
<img src="{$me->getPhoto('s')}">
{/if}
</span>
<div class="bubble">
{if="preg_match('#^\?OTR#', $value->body)"}
<i class="md md-lock"></i> {$c->__('message.encrypted')}
{else}
{$value->body|prepareString}
{/if}
<span class="info">{$value->delivered|strtotime|prepareDate}</span>
</div>
</li>
{/loop}
</ul>

26
app/widgets/Chat/_chat_smiley.tpl

@ -0,0 +1,26 @@
<section>
<h3>{$c->__('chat.smileys')}</h3>
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
</section>
<div>
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>
</div>

16
app/widgets/Chat/chat.js

@ -0,0 +1,16 @@
var Chats = {
message: function(jid, html) {
movim_append('messages' + jid, html);
Chats.scroll(jid);
},
addSmiley: function(smiley) {
},
sendMessage: function(n, jid)
{
var text = n.value;
n.value = "";
n.focus();
return encodeURIComponent(text);
},
}

13
app/widgets/Chat/locales.ini

@ -0,0 +1,13 @@
[message]
message.published = 'Message Published'
message.encrypted = 'Encrypted message'
message.composing = 'Composing...'
message.paused = 'Paused...'
[chat]
chat.attention = '%s needs your attention'
chat.placeholder = 'Your message here...'
chat.smileys = 'Smileys'
chatroom.connected = 'Connected to the chatroom'
chatroom.disconnected = 'Disconnected from the chatroom'

12
app/widgets/Chats/Chats.php

@ -0,0 +1,12 @@
<?php
class Chats extends WidgetCommon
{
function load()
{
}
function display()
{
}
}

0
app/widgets/Chats/_chats.tpl

0
app/widgets/Chats/chats.tpl

2
app/widgets/Contact/_contact_delete.tpl

@ -3,7 +3,7 @@
<br />
<h4 class="gray">{$c->__('delete.text')}</h4>
</section>
<div class="actions no_bar">
<div class="no_bar">
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.cancel')}
</a>

4
app/widgets/Contact/_contact_edit.tpl

@ -1,5 +1,5 @@
<section>
<h2>{$c->__('edit.title')}</h2>
<h3>{$c->__('edit.title')}</h3>
<form name="manage">
<div>
<input
@ -30,7 +30,7 @@
<input type="hidden" name="jid" value="{$contact->jid}"/>
</form>
</section>
<div class="actions">
<div>
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>

2
app/widgets/Contact/locales.ini

@ -33,7 +33,7 @@ client.title = 'Client Informations'
last_registered = 'Last registered'
[edit]
edit.title = 'Manage'
edit.title = 'Edit'
edit.alias = 'Alias'
edit.group = 'Group'
edit.updated = 'Contact updated'

2
app/widgets/Dialog/dialog.tpl

@ -1 +1 @@
<div id="dialog" class="dialog"></div>
<div id="dialog" class="dialog actions"></div>

3
app/widgets/Header/_header_chat.tpl

@ -1,6 +1,5 @@
<header>
<header id="header">
<span id="menu" class="on_mobile icon" onclick="MovimTpl.showMenu()"><i class="md md-menu"></i></span>
<span id="back" class="on_mobile icon" onclick="MovimTpl.hidePanel()"><i class="md md-arrow-back"></i></span>
<span class="on_desktop icon"><i class="md md-forum"></i></span>
<h2>{$c->__('page.chats')}</h2>
</header>

2
app/widgets/Navigation/navigation.tpl

@ -3,7 +3,7 @@
<div class="on_mobile control">
<i onclick="movim_remove_class('body > nav', 'active')" class="md md-arrow-back"></i>
</div>
<span class="icon bubble"><i class="md md-camera-roll"></i></span>
<span class="icon bubble"><i class="md md-cloud-queue"></i></span>
Movim
</li>
<a class="classic" href="{$c->route('root')}">

3
app/widgets/Presence/_presence_list.tpl

@ -15,7 +15,6 @@
</div>
</form>
</li>
<li class="subheader">{$c->__('status.presence')}</li>
<li onclick="{$callchat}">
<span class="icon bubble color small green"></span>
{$txt[1]}
@ -39,7 +38,7 @@
</li>
</ul>
</section>
<div class="actions">
<div>
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>

4
app/widgets/Roster/_roster_search.tpl

@ -1,6 +1,6 @@
<section>
<h3>{$c->__('roster.search')}</h3>
<ul class="simple">
<li class="subheader">{$c->__('roster.search')}</li>
<li>
<form name="add">
<div>
@ -23,7 +23,7 @@
</div>
</section>
<div class="actions">
<div>
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>

4
themes/material/css/color.css

@ -139,6 +139,10 @@ body.green .oppose .bubble,
body.green ul li span.counter,
body.green main > header { background-color: #689F38; color: white; border-color: #689F38; }
/* 200 */
body.green .oppose .bubble a,
body.green main > header a { color: #DCEDC8; }
body.green .tabs,
body.green .button,
body.green input[type=button],

3
themes/material/css/form.css

@ -24,6 +24,7 @@ form > div > textarea {
resize: none;
font-size: 2rem;
font-family: sans-serif;
box-sizing: border-box;
}
form > div > input,
@ -35,6 +36,8 @@ form > div > textarea {
background-color: transparent;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
margin-bottom: 1px;
overflow: hidden; /* Fixme */
}
form > div > input:focus,

7
themes/material/css/list.css

@ -120,7 +120,11 @@ ul li > div.control + p {
padding-right: 6rem;
}
ul li form > div.control {
ul li > form {
max-width: 90%;
}
ul li > form > div.control {
float: right;
min-height: 0;
padding-top: 2rem;
@ -132,6 +136,7 @@ ul.thin li form > div.control {
ul li span.info {
float: right;
margin-left: 1rem;
}
/* Counter */

72
themes/material/css/style.css

@ -243,6 +243,19 @@ main section > div:first-child:nth-last-child(2) ~ div {
transition: right 0.2s ease;
}
main section > div > div.contained { /* Specific behaviour when the scroll need to be inside the block */
height: calc(100% - 9rem);
overflow-y: scroll;
position: absolute;
max-width: 100%;
width: 100%;
}
main section > div > div.contained > * {
max-width: 100rem;
margin: 0 auto;
}
@media screen and (max-width: 1024px) {
/* Two blocks*/
main section > div:first-child:nth-last-child(2) {
@ -405,7 +418,7 @@ header.big p {
height: 100%;
padding-top: 3rem;
padding-bottom: 8rem;
padding-bottom: 7rem;
}
.dialog > section {
@ -432,34 +445,65 @@ header.big p {
left: 1rem;
}
.dialog .actions {
@media screen and (max-width: 600px) {
.dialog {
width: 90%;
height: 80%;
min-height: 0;
min-width: 0;
max-height: 90%;
margin-left: -45%;
margin-top: 0;
top: 10%;
}
}
/* Actions bar */
.actions {
margin-bottom: 7rem;
}
.actions > div:last-child {
background-color: white;
width: 100%;
box-sizing: border-box;
text-align: right;
bottom: 0;
padding: 0.5rem 2rem;
position: absolute;
position: relative;
border-top: 1px solid rgba(0, 0, 0, 0.12);
}
.dialog .actions.no_bar {
.actions > div.no_bar:last-child {
border-top: none;
}
@media screen and (max-width: 600px) {
.dialog {
width: 90%;
height: 80%;
min-height: 0;
min-width: 0;
max-height: 90%;
margin-left: -45%;
margin-top: 0;
top: 10%;
.actions.fixed > div:last-child {
position: fixed;
min-height: 7rem;
max-width: calc(100% - 5rem);
width: 100%;
padding: 0;
}
main section > div:first-child:nth-last-child(2) ~ div .actions.fixed > div:last-child {
max-width: calc(75% - 5rem);
}
.actions.fixed > div:last-child > * { /* Little hack to fake the 100% width that overflow the parent */
max-width: 100rem;
margin: 0 auto;
}
@media screen and (max-width: 1024px) { /* Known bug, on some intermediary resolution, the content is cropped */
main section > div:first-child:nth-last-child(2) ~ div .actions.fixed > div:last-child {
max-width: 100%;
}
}
/* Snackbar - Toast */
.snackbar,

Loading…
Cancel
Save