From c725fd23ec1ed248df4bbf49cfc96e75632a481e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaussoin=20Timoth=C3=A9e?= Date: Fri, 19 Dec 2014 22:10:46 +0100 Subject: [PATCH] - Continue the implementation of the Chat - Fix the navigation panel (new organisation) - Fix the Roster - Contact edit and Contac delete --- app/assets/js/movim_tpl.js | 7 ++ app/assets/js/movim_websocket.js | 2 +- app/views/chat.tpl | 4 +- app/widgets/Chat/Chat.php | 113 +++++++++++++++++++++++- app/widgets/Chat/_chat.tpl | 67 ++++++++++---- app/widgets/Chat/_chat_header.tpl | 15 ++-- app/widgets/Chat/_chat_messages.tpl | 21 +++++ app/widgets/Chat/_chat_smiley.tpl | 26 ++++++ app/widgets/Chat/chat.js | 16 ++++ app/widgets/Chat/locales.ini | 13 +++ app/widgets/Chats/Chats.php | 12 +++ app/widgets/Chats/_chats.tpl | 0 app/widgets/Chats/chats.tpl | 0 app/widgets/Contact/_contact_delete.tpl | 2 +- app/widgets/Contact/_contact_edit.tpl | 4 +- app/widgets/Contact/locales.ini | 2 +- app/widgets/Dialog/dialog.tpl | 2 +- app/widgets/Header/_header_chat.tpl | 3 +- app/widgets/Navigation/navigation.tpl | 2 +- app/widgets/Presence/_presence_list.tpl | 3 +- app/widgets/Roster/_roster_search.tpl | 4 +- themes/material/css/color.css | 4 + themes/material/css/form.css | 3 + themes/material/css/list.css | 7 +- themes/material/css/style.css | 72 ++++++++++++--- 25 files changed, 346 insertions(+), 58 deletions(-) create mode 100644 app/widgets/Chat/_chat_messages.tpl create mode 100644 app/widgets/Chat/_chat_smiley.tpl create mode 100644 app/widgets/Chat/chat.js create mode 100644 app/widgets/Chat/locales.ini create mode 100644 app/widgets/Chats/Chats.php create mode 100644 app/widgets/Chats/_chats.tpl create mode 100644 app/widgets/Chats/chats.tpl diff --git a/app/assets/js/movim_tpl.js b/app/assets/js/movim_tpl.js index 9d603d1a2..fbc10c8c6 100755 --- a/app/assets/js/movim_tpl.js +++ b/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'); } diff --git a/app/assets/js/movim_websocket.js b/app/assets/js/movim_websocket.js index 5b5a94174..a9505fcb4 100755 --- a/app/assets/js/movim_websocket.js +++ b/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); diff --git a/app/views/chat.tpl b/app/views/chat.tpl index d9e8417af..dcf31c80e 100644 --- a/app/views/chat.tpl +++ b/app/views/chat.tpl @@ -7,8 +7,6 @@ widget('Header'); ?>
widget('Roster');?> -
- widget('Chat');?> -
+ widget('Chat');?>
diff --git a/app/widgets/Chat/Chat.php b/app/widgets/Chat/Chat.php index e05c939b2..f24bfdfdc 100644 --- a/app/widgets/Chat/Chat.php +++ b/app/widgets/Chat/Chat.php @@ -1,11 +1,43 @@ 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() diff --git a/app/widgets/Chat/_chat.tpl b/app/widgets/Chat/_chat.tpl index af3777f29..a32c42708 100644 --- a/app/widgets/Chat/_chat.tpl +++ b/app/widgets/Chat/_chat.tpl @@ -1,17 +1,50 @@ - +
+
+ {$messages} +
+
+
    +
  • + + + +
    + +
    +
    +
    + + +
    +
    +
  • +
+
+
diff --git a/app/widgets/Chat/_chat_header.tpl b/app/widgets/Chat/_chat_header.tpl index 1eb04f12a..58d29e94e 100644 --- a/app/widgets/Chat/_chat_header.tpl +++ b/app/widgets/Chat/_chat_header.tpl @@ -2,15 +2,14 @@ -

{$jid}

+{if="$contact != null"} +

{$contact->getTrueName()}

+{else} +

{$jid}

+{/if} diff --git a/app/widgets/Chat/_chat_messages.tpl b/app/widgets/Chat/_chat_messages.tpl new file mode 100644 index 000000000..ba7cd9772 --- /dev/null +++ b/app/widgets/Chat/_chat_messages.tpl @@ -0,0 +1,21 @@ + diff --git a/app/widgets/Chat/_chat_smiley.tpl b/app/widgets/Chat/_chat_smiley.tpl new file mode 100644 index 000000000..e224d9afa --- /dev/null +++ b/app/widgets/Chat/_chat_smiley.tpl @@ -0,0 +1,26 @@ +
+

{$c->__('chat.smileys')}

+ + + + + + + + + + + + + + + + + +
123123
123123
+
+
+ + {$c->__('button.close')} + +
diff --git a/app/widgets/Chat/chat.js b/app/widgets/Chat/chat.js new file mode 100644 index 000000000..b69fc8546 --- /dev/null +++ b/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); + }, +} diff --git a/app/widgets/Chat/locales.ini b/app/widgets/Chat/locales.ini new file mode 100644 index 000000000..c4b6c94aa --- /dev/null +++ b/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' diff --git a/app/widgets/Chats/Chats.php b/app/widgets/Chats/Chats.php new file mode 100644 index 000000000..02e4d5f88 --- /dev/null +++ b/app/widgets/Chats/Chats.php @@ -0,0 +1,12 @@ +

{$c->__('delete.text')}

-
+
{$c->__('button.cancel')} diff --git a/app/widgets/Contact/_contact_edit.tpl b/app/widgets/Contact/_contact_edit.tpl index 73a8ceab8..5d4c14eb2 100644 --- a/app/widgets/Contact/_contact_edit.tpl +++ b/app/widgets/Contact/_contact_edit.tpl @@ -1,5 +1,5 @@
-

{$c->__('edit.title')}

+

{$c->__('edit.title')}

-
+
{$c->__('button.close')} diff --git a/app/widgets/Contact/locales.ini b/app/widgets/Contact/locales.ini index 2043cfbff..4408a4270 100644 --- a/app/widgets/Contact/locales.ini +++ b/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' diff --git a/app/widgets/Dialog/dialog.tpl b/app/widgets/Dialog/dialog.tpl index 9fb714908..c751a1dc2 100644 --- a/app/widgets/Dialog/dialog.tpl +++ b/app/widgets/Dialog/dialog.tpl @@ -1 +1 @@ -
+
diff --git a/app/widgets/Header/_header_chat.tpl b/app/widgets/Header/_header_chat.tpl index ed8432e89..dd3d4e9f6 100644 --- a/app/widgets/Header/_header_chat.tpl +++ b/app/widgets/Header/_header_chat.tpl @@ -1,6 +1,5 @@ -
+ diff --git a/app/widgets/Navigation/navigation.tpl b/app/widgets/Navigation/navigation.tpl index de6e5777b..5e679d579 100644 --- a/app/widgets/Navigation/navigation.tpl +++ b/app/widgets/Navigation/navigation.tpl @@ -3,7 +3,7 @@
- + Movim diff --git a/app/widgets/Presence/_presence_list.tpl b/app/widgets/Presence/_presence_list.tpl index 748036e56..dad1b4ce0 100755 --- a/app/widgets/Presence/_presence_list.tpl +++ b/app/widgets/Presence/_presence_list.tpl @@ -15,7 +15,6 @@
-
  • {$c->__('status.presence')}
  • {$txt[1]} @@ -39,7 +38,7 @@
  • -
    +
    {$c->__('button.close')} diff --git a/app/widgets/Roster/_roster_search.tpl b/app/widgets/Roster/_roster_search.tpl index 50895d7dc..949992392 100644 --- a/app/widgets/Roster/_roster_search.tpl +++ b/app/widgets/Roster/_roster_search.tpl @@ -1,6 +1,6 @@
    +

    {$c->__('roster.search')}

      -
    • {$c->__('roster.search')}
    • @@ -23,7 +23,7 @@
    -
    +
    {$c->__('button.close')} diff --git a/themes/material/css/color.css b/themes/material/css/color.css index 6b4c266c9..68d31a121 100644 --- a/themes/material/css/color.css +++ b/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], diff --git a/themes/material/css/form.css b/themes/material/css/form.css index a5faa1d3a..e581cccf5 100644 --- a/themes/material/css/form.css +++ b/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, diff --git a/themes/material/css/list.css b/themes/material/css/list.css index 4d3ba50de..8109789fb 100644 --- a/themes/material/css/list.css +++ b/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 */ diff --git a/themes/material/css/style.css b/themes/material/css/style.css index 3b8dcb500..6e9fb8d40 100644 --- a/themes/material/css/style.css +++ b/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,