Browse Source

- Split the Chats widget in two (and create Rooms widget out of it)

- Continue MUC implementation with join/disconnect
- Fix MovimWebsocket initialisation
- Change some icons
- Add a empty view in Chat
pull/16/head
Jaussoin Timothée 11 years ago
parent
commit
f044355d39
  1. 13
      app/assets/js/movim_websocket.js
  2. 3
      app/models/conference/ConferenceDAO.php
  3. 5
      app/views/chat.tpl
  4. 47
      app/widgets/Chat/Chat.php
  5. 4
      app/widgets/Chat/_chat_empty.tpl
  6. 2
      app/widgets/Chat/_chat_header.tpl
  7. 9
      app/widgets/Chat/_chat_header_room.tpl
  8. 3
      app/widgets/Chat/chat.tpl
  9. 2
      app/widgets/Chat/locales.ini
  10. 154
      app/widgets/Chats/Chats.php
  11. 9
      app/widgets/Chats/_chats.tpl
  12. 11
      app/widgets/Chats/chats.js
  13. 13
      app/widgets/Chats/chats.tpl
  14. 15
      app/widgets/Chats/locales.ini
  15. 2
      app/widgets/Header/_header_chat.tpl
  16. 2
      app/widgets/Navigation/navigation.tpl
  17. 179
      app/widgets/Rooms/Rooms.php
  18. 17
      app/widgets/Rooms/_rooms.tpl
  19. 4
      app/widgets/Rooms/_rooms_add.tpl
  20. 2
      app/widgets/Rooms/_rooms_remove.tpl
  21. 17
      app/widgets/Rooms/locales.ini
  22. 33
      app/widgets/Rooms/rooms.js
  23. 1
      app/widgets/Rooms/rooms.tpl
  24. 5
      themes/material/css/style.css

13
app/assets/js/movim_websocket.js

@ -19,18 +19,17 @@ WebSocket.prototype.admin = function(key) {
var MovimWebsocket = {
connection: null,
attached: null,
attached: new Array(),
unregistered: false,
launchAttached : function() {
for(var i = 0; i < this.attached.length; i++) {
this.attached[i]();
for(var i = 0; i < MovimWebsocket.attached.length; i++) {
MovimWebsocket.attached[i]();
}
},
init : function() {
this.connection = new WebSocket('ws://' + BASE_HOST + ':8080');
this.attached = new Array();
this.connection.onopen = function(e) {
console.log("Connection established!");
@ -138,5 +137,7 @@ window.onbeforeunload = function() {
MovimWebsocket.connection.close()
};
// And we start it
MovimWebsocket.init();
movim_add_onload(function() {
// And we start it
MovimWebsocket.init();
});

3
app/models/conference/ConferenceDAO.php

@ -69,7 +69,8 @@ class ConferenceDAO extends SQL {
function getAll() {
$this->_sql = '
select * from conference
where jid = :jid';
where jid = :jid
order by conference';
$this->prepare(
'Conference',

5
app/views/chat.tpl

@ -7,7 +7,10 @@
<main>
<?php $this->widget('Header'); ?>
<section>
<?php $this->widget('Chats');?>
<div>
<?php $this->widget('Chats');?>
<?php $this->widget('Rooms');?>
</div>
<?php $this->widget('Chat');?>
</section>
</main>

47
app/widgets/Chat/Chat.php

@ -3,7 +3,6 @@
use Moxl\Xec\Action\Message\Composing;
use Moxl\Xec\Action\Message\Paused;
use Moxl\Xec\Action\Message\Publish;
use Moxl\Xec\Action\Presence\Unavailable;
class Chat extends WidgetCommon
{
@ -28,7 +27,8 @@ class Chat extends WidgetCommon
$contact = $cd->get($from);
if($contact != null
&& !preg_match('#^\?OTR#', $message->body)) {
&& !preg_match('#^\?OTR#', $message->body)
&& $message->type != 'groupchat') {
Notification::append('chat|'.$from, $contact->getTrueName(), $message->body, $contact->getPhoto('s'), 4);
}
// If the message is from me
@ -87,16 +87,20 @@ class Chat extends WidgetCommon
* @brief Get a discussion
* @parem string $jid
*/
function ajaxGet($jid)
function ajaxGet($jid = null)
{
$html = $this->prepareChat($jid);
$header = $this->prepareHeader($jid);
Header::fill($header);
RPC::call('movim_fill', 'chat_widget', $html);
RPC::call('MovimTpl.scrollPanel');
RPC::call('MovimTpl.showPanel');
if($jid == null) {
RPC::call('movim_fill', 'chat_widget', $this->prepareEmpty());
} else {
$html = $this->prepareChat($jid);
$header = $this->prepareHeader($jid);
Header::fill($header);
RPC::call('movim_fill', 'chat_widget', $html);
RPC::call('MovimTpl.scrollPanel');
RPC::call('MovimTpl.showPanel');
}
}
/**
@ -229,20 +233,6 @@ class Chat extends WidgetCommon
return $view->draw('_chat_header_room', true);
}
/**
* @brief Exit a room
*
* @param string $room
*/
function ajaxExitRoom($room)
{
$session = \Sessionx::start();
$pu = new Unavailable;
$pu->setTo($room)
->setResource($session->username)
->request();
}
function prepareChat($jid, $muc = false)
{
@ -310,8 +300,13 @@ class Chat extends WidgetCommon
return $view->draw('_chat_messages', true);
}
function display()
function prepareEmpty()
{
$view = $this->tpl();
return $view->draw('_chat_empty', true);
}
function display()
{
}
}

4
app/widgets/Chat/_chat_empty.tpl

@ -0,0 +1,4 @@
<div class="placeholder icon forum">
<h1>{$c->__('chat.empty_title')}</h1>
<h4>{$c->__('chat.empty_text')}</h4>
</div>

2
app/widgets/Chat/_chat_header.tpl

@ -1,4 +1,4 @@
<span id="back" class="icon" onclick="MovimTpl.hidePanel()"><i class="md md-arrow-back"></i></span>
<span id="back" class="icon" onclick="MovimTpl.hidePanel(); Chat_ajaxGet();"><i class="md md-arrow-back"></i></span>
<ul class="active">
<li onclick="Chats_ajaxClose('{$jid}'); MovimTpl.hidePanel();">

9
app/widgets/Chat/_chat_header_room.tpl

@ -1,10 +1,15 @@
<span id="back" class="icon" onclick="MovimTpl.hidePanel()"><i class="md md-arrow-back"></i></span>
<span id="back" class="icon" onclick="MovimTpl.hidePanel(); Chat_ajaxGet();"><i class="md md-arrow-back"></i></span>
<ul class="active">
<li onclick="Chats_ajaxRemoveRoomConfirmation('{$room}')">
<li onclick="Rooms_ajaxRemoveConfirm('{$room}')">
<span class="icon">
<i class="md md-delete"></i>
</span>
</li>
<li onclick="Rooms_ajaxExit('{$room}'); MovimTpl.hidePanel();">
<span class="icon">
<i class="md md-close"></i>
</span>
</li>
</ul>
<h2>{$room}</h2>

3
app/widgets/Chat/chat.tpl

@ -1,2 +1 @@
<div id="chat_widget">
</div>
<div id="chat_widget">{$c->prepareEmpty()}</div>

2
app/widgets/Chat/locales.ini

@ -8,6 +8,8 @@ message.paused = 'Paused...'
chat.attention = '%s needs your attention'
chat.placeholder = 'Your message here...'
chat.smileys = 'Smileys'
chat.empty_title = 'Chat'
chat.empty_text = 'Discuss with your contacts'
chatroom.connected = 'Connected to the chatroom'
chatroom.disconnected = 'Disconnected from the chatroom'

154
app/widgets/Chats/Chats.php

@ -11,7 +11,7 @@ class Chats extends WidgetCommon
$this->addjs('chats.js');
$this->registerEvent('carbons', 'onMessage');
$this->registerEvent('message', 'onMessage');
$this->registerEvent('bookmark_set_handle', 'onBookmark');
//$this->registerEvent('bookmark_set_handle', 'onBookmark');
$this->registerEvent('presence', 'onPresence', 'chat');
}
@ -19,20 +19,22 @@ class Chats extends WidgetCommon
{
$message = $packet->content;
// If the message is from me
if($message->session == $message->jidto) {
$from = $message->jidfrom;
} else {
$from = $message->jidto;
}
if($message->type != 'groupchat') {
// If the message is from me
if($message->session == $message->jidto) {
$from = $message->jidfrom;
} else {
$from = $message->jidto;
}
$chats = Cache::c('chats');
if(!array_key_exists($from, $chats)) {
$this->ajaxOpen($from);
} else {
// TODO notification overwrite issue
//RPC::call('movim_replace', $from, $this->prepareChat($from));
RPC::call('Chats.refresh');
$chats = Cache::c('chats');
if(!array_key_exists($from, $chats)) {
$this->ajaxOpen($from);
} else {
// TODO notification overwrite issue
//RPC::call('movim_replace', $from, $this->prepareChat($from));
RPC::call('Chats.refresh');
}
}
}
@ -49,14 +51,6 @@ class Chats extends WidgetCommon
}
}
function onBookmark()
{
RPC::call('movim_fill', 'chats_widget_list', $this->prepareChats());
Notification::append(null, $this->__('bookmarks.updated'));
RPC::call('Chats.refresh');
RPC::call('MovimTpl.hidePanel');
}
function ajaxOpen($jid)
{
$chats = Cache::c('chats');
@ -99,122 +93,11 @@ class Chats extends WidgetCommon
Dialog::fill($view->draw('_chats_add', true), true);
}
/**
* @brief Display the add room form
*/
function ajaxAddRoom()
{
$view = $this->tpl();
$cd = new \Modl\ContactDAO;
$view->assign('me', $cd->get());
Dialog::fill($view->draw('_chats_add_room', true));
}
/**
* @brief Display the remove room confirmation
*/
function ajaxRemoveRoomConfirmation($room)
{
$view = $this->tpl();
$view->assign('room', $room);
Dialog::fill($view->draw('_chats_remove_room', true));
}
/**
* @brief Remove a room
*/
function ajaxRemoveRoom($room)
{
$cd = new \modl\ConferenceDAO();
$cd->deleteNode($room);
$this->setBookmark();
}
/**
* @brief Join a chatroom
*/
function ajaxChatroomJoin($jid, $nickname)
{
$p = new Muc;
$p->setTo($jid)
->setNickname($nickname)
->request();
}
/**
* @brief Display the add room form
*/
function ajaxChatroomAdd($form)
{
if(!filter_var($form['jid'], FILTER_VALIDATE_EMAIL)) {
Notification::append(null, $this->__('chatrooms.bad_id'));
} elseif(trim($form['name']) == '') {
Notification::append(null, $this->__('chatrooms.empty_name'));
} else {
$item = array(
'type' => 'conference',
'name' => $form['name'],
'autojoin' => $form['autojoin'],
'nick' => $form['nick'],
'jid' => $form['jid']);
$this->setBookmark($item);
RPC::call('Dialog.clear');
}
}
private function setBookmark($item = false)
{
$arr = array();
if($item) {
array_push($arr, $item);
}
$sd = new \modl\SubscriptionDAO();
$cd = new \modl\ConferenceDAO();
foreach($sd->getSubscribed() as $s) {
array_push($arr,
array(
'type' => 'subscription',
'server' => $s->server,
'title' => $s->title,
'subid' => $s->subid,
'tags' => unserialize($s->tags),
'node' => $s->node));
}
foreach($cd->getAll() as $c) {
array_push($arr,
array(
'type' => 'conference',
'name' => $c->name,
'autojoin' => $c->autojoin,
'nick' => $c->nick,
'jid' => $c->conference));
}
$b = new Set;
$b->setArr($arr)
->setTo($this->user->getLogin())
->request();
}
function prepareChats()
{
$chats = Cache::c('chats');
$view = $this->tpl();
$cod = new \modl\ConferenceDAO();
$view->assign('conferences', $cod->getAll());
$view->assign('chats', array_reverse($chats));
return $view->draw('_chats', true);
@ -247,11 +130,6 @@ class Chats extends WidgetCommon
return $view->draw('_chats_item', true);
}
function prepareChatrooms()
{
return $view->draw('_chatrooms', true);
}
function display()
{
$this->view->assign('list', $this->prepareChats());

9
app/widgets/Chats/_chats.tpl

@ -8,12 +8,3 @@
{loop="$chats"}
{$c->prepareChat($key)}
{/loop}
<li class="subheader">
{$c->__('chatrooms.title')}
</li>
{loop="$conferences"}
<li data-jid="{$value->conference}" data-nick="{$value->nick}" class="room">
<span class="icon bubble color {$value->name|stringToColor}">{$value->name|firstLetterCapitalize}</span>
<span>{$value->name}</span>
</li>
{/loop}

11
app/widgets/Chats/chats.js

@ -6,12 +6,13 @@ var Chats = {
{
if(items[i].dataset.jid != null) {
items[i].onclick = function(e) {
if(movim_has_class(this, 'room')) {
/*if(movim_has_class(this, 'room')) {
Chats_ajaxChatroomJoin(this.dataset.jid, this.dataset.nick);
Chat_ajaxGetRoom(this.dataset.jid);
} else {
Chat_ajaxGet(this.dataset.jid);
}
}*/
Chat_ajaxGet(this.dataset.jid);
Chats.reset(items);
Notification_ajaxClear('chat|' + this.dataset.jid);
Notification_ajaxCurrent('chat|' + this.dataset.jid);
@ -28,12 +29,14 @@ var Chats = {
i++;
}
Chat_ajaxGet();
if(window.innerWidth > 1024 && !MovimTpl.isPanel()) {
/*if(window.innerWidth > 1024 && !MovimTpl.isPanel()) {
Notification.notifs_key = 'chat|' + items[0].dataset.jid;
Notification_ajaxCurrent(Notification.notifs_key);
items[0].click();
}
}*/
},
reset: function(list) {

13
app/widgets/Chats/chats.tpl

@ -1,10 +1,3 @@
<div id="chats_widget">
<ul id="chats_widget_list" class="thick active divided">
{$list}
</ul>
<!--
<a class="button action color">
<i class="md md-playlist-add"></i>
</a>
-->
</div>
<ul id="chats_widget_list" class="thick active divided">
{$list}
</ul>

15
app/widgets/Chats/locales.ini

@ -1,24 +1,9 @@
[chats]
chats.empty = 'Open a new conversation here by clicking on the plus button bellow'
chats.add = 'Chat with a contact'
chats.add_room = 'Add a chatroom'
[message]
message.encrypted = 'Encrypted message'
[chatrooms]
chatrooms.title = 'Chatrooms'
chatrooms.id = 'Chat Room ID'
chatrooms.name = 'Name'
chatrooms.name_placeholder = 'My Favorite Room'
chatrooms.nickname = 'Nickname'
chatrooms.bad_id = 'Bad Chatroom ID'
chatrooms.empty_name = 'Empty name'
chatrooms.remove_title = 'Remove a chatroom'
chatrooms.remove_text = 'You are going to remove the following chatroom. Please confirm your action.'
[add]
button.chat = 'Chat'
[bookmarks]
bookmarks.updated = 'Bookmarks updated'

2
app/widgets/Header/_header_chat.tpl

@ -4,7 +4,7 @@
<i class="md md-person-add"></i>
</span>
</li>
<li onclick="Chats_ajaxAddRoom()">
<li onclick="Rooms_ajaxAdd()">
<span class="icon">
<i class="md md-group-add"></i>
</span>

2
app/widgets/Navigation/navigation.tpl

@ -8,7 +8,7 @@
</li>
<a class="classic" href="{$c->route('root')}">
<li>
<span class="icon"><i class="md md-speaker-notes"></i></span>
<span class="icon"><i class="md md-view-list"></i></span>
<span data-key="news" class="counter"></span>
<span>{$c->__('page.news')}</span>
</li>

179
app/widgets/Rooms/Rooms.php

@ -0,0 +1,179 @@
<?php
use Moxl\Xec\Action\Presence\Muc;
use Moxl\Xec\Action\Bookmark\Get;
use Moxl\Xec\Action\Bookmark\Set;
use Moxl\Xec\Action\Presence\Unavailable;
class Rooms extends WidgetCommon
{
function load()
{
$this->addjs('rooms.js');
$this->registerEvent('bookmark_set_handle', 'onBookmark');
$this->registerEvent('presence_muc_handle', 'onConnected');
$this->registerEvent('presence_unavailable_handle', 'onDisconnected');
}
function onBookmark()
{
RPC::call('movim_fill', 'rooms_widget', $this->prepareRooms());
Notification::append(null, $this->__('bookmarks.updated'));
RPC::call('Rooms.refresh');
RPC::call('MovimTpl.hidePanel');
}
function onConnected()
{
RPC::call('movim_fill', 'rooms_widget', $this->prepareRooms());
Notification::append(null, $this->__('chatrooms.connected'));
RPC::call('Rooms.refresh');
}
function onDisconnected()
{
// We reset the Chat view
$c = new Chat();
$c->ajaxGet();
RPC::call('movim_fill', 'rooms_widget', $this->prepareRooms());
Notification::append(null, $this->__('chatrooms.disconnected'));
RPC::call('Rooms.refresh');
}
/**
* @brief Display the add room form
*/
function ajaxAdd()
{
$view = $this->tpl();
$cd = new \Modl\ContactDAO;
$view->assign('me', $cd->get());
Dialog::fill($view->draw('_rooms_add', true));
}
/**
* @brief Display the remove room confirmation
*/
function ajaxRemoveConfirm($room)
{
$view = $this->tpl();
$view->assign('room', $room);
Dialog::fill($view->draw('_rooms_remove', true));
}
/**
* @brief Remove a room
*/
function ajaxRemove($room)
{
$cd = new \modl\ConferenceDAO();
$cd->deleteNode($room);
$this->setBookmark();
}
/**
* @brief Join a chatroom
*/
function ajaxJoin($jid, $nickname)
{
$p = new Muc;
$p->setTo($jid)
->setNickname($nickname)
->request();
}
/**
* @brief Exit a room
*
* @param string $room
*/
function ajaxExit($room)
{
$session = \Sessionx::start();
$pu = new Unavailable;
$pu->setTo($room)
->setResource($session->username)
->request();
}
/**
* @brief Display the add room form
*/
function ajaxChatroomAdd($form)
{
if(!filter_var($form['jid'], FILTER_VALIDATE_EMAIL)) {
Notification::append(null, $this->__('chatrooms.bad_id'));
} elseif(trim($form['name']) == '') {
Notification::append(null, $this->__('chatrooms.empty_name'));
} else {
$item = array(
'type' => 'conference',
'name' => $form['name'],
'autojoin' => $form['autojoin'],
'nick' => $form['nick'],
'jid' => $form['jid']);
$this->setBookmark($item);
RPC::call('Dialog.clear');
}
}
private function setBookmark($item = false)
{
$arr = array();
if($item) {
array_push($arr, $item);
}
$sd = new \modl\SubscriptionDAO();
$cd = new \modl\ConferenceDAO();
foreach($sd->getSubscribed() as $s) {
array_push($arr,
array(
'type' => 'subscription',
'server' => $s->server,
'title' => $s->title,
'subid' => $s->subid,
'tags' => unserialize($s->tags),
'node' => $s->node));
}
foreach($cd->getAll() as $c) {
array_push($arr,
array(
'type' => 'conference',
'name' => $c->name,
'autojoin' => $c->autojoin,
'nick' => $c->nick,
'jid' => $c->conference));
}
$b = new Set;
$b->setArr($arr)
->setTo($this->user->getLogin())
->request();
}
function prepareRooms()
{
$view = $this->tpl();
$cod = new \modl\ConferenceDAO();
$view->assign('conferences', $cod->getAll());
return $view->draw('_rooms', true);
}
function display()
{
$this->view->assign('list', $this->prepareRooms());
}
}

17
app/widgets/Rooms/_rooms.tpl

@ -0,0 +1,17 @@
<ul class="thick divided active">
<li class="subheader">
{$c->__('chatrooms.title')}
</li>
{loop="$conferences"}
<li data-jid="{$value->conference}"
data-nick="{$value->nick}"
class="room {if="$value->status == 1"}online{/if}">
{if="$value->status == 1"}
<span class="icon bubble color {$value->name|stringToColor}"><i class="md md-people"></i></span>
{else}
<span class="icon bubble color {$value->name|stringToColor}"><i class="md md-people-outline"></i></span>
{/if}
<span>{$value->name}</span>
</li>
{/loop}
</ul>

4
app/widgets/Chats/_chats_add_room.tpl → app/widgets/Rooms/_rooms_add.tpl

@ -1,6 +1,6 @@
<section>
<form name="bookmarkmucadd">
<h3>{$c->__('chats.add_room')}</h3>
<h3>{$c->__('rooms.add')}</h3>
<div>
<label>{$c->__('chatrooms.id')}</label>
@ -30,7 +30,7 @@
</a>
<a
class="button flat"
onclick="Chats_ajaxChatroomAdd(movim_parse_form('bookmarkmucadd'));">
onclick="Rooms_ajaxChatroomAdd(movim_parse_form('bookmarkmucadd'));">
{$c->__('button.add')}
</a>
</div>

2
app/widgets/Chats/_chats_remove_room.tpl → app/widgets/Rooms/_rooms_remove.tpl

@ -12,7 +12,7 @@
<a
name="submit"
class="button flat"
onclick="Chats_ajaxRemoveRoom('{$room}'); Dialog.clear()">
onclick="Rooms_ajaxRemove('{$room}'); Dialog.clear()">
{$c->__('button.remove')}
</a>
</div>

17
app/widgets/Rooms/locales.ini

@ -0,0 +1,17 @@
rooms.add = 'Add a chatroom'
[chatrooms]
chatrooms.title = 'Chatrooms'
chatrooms.id = 'Chat Room ID'
chatrooms.name = 'Name'
chatrooms.name_placeholder = 'My Favorite Room'
chatrooms.nickname = 'Nickname'
chatrooms.bad_id = 'Bad Chatroom ID'
chatrooms.empty_name = 'Empty name'
chatrooms.remove_title = 'Remove a chatroom'
chatrooms.remove_text = 'You are going to remove the following chatroom. Please confirm your action.'
chatrooms.connected = 'Connected to the chatroom'
chatrooms.disconnected = 'Disconnected from the chatroom'
[bookmarks]
bookmarks.updated = 'Bookmarks updated'

33
app/widgets/Rooms/rooms.js

@ -0,0 +1,33 @@
var Rooms = {
refresh: function() {
var items = document.querySelectorAll('#rooms_widget ul li:not(.subheader)');
var i = 0;
while(i < items.length)
{
if(items[i].dataset.jid != null) {
items[i].onclick = function(e) {
console.log(this);
if(!movim_has_class(this, 'online')) {
Rooms_ajaxJoin(this.dataset.jid, this.dataset.nick);
}
Chat_ajaxGetRoom(this.dataset.jid);
Chats.reset(items);
movim_add_class(this, 'active');
}
}
i++;
}
},
reset: function(list) {
for(i = 0; i < list.length; i++) {
movim_remove_class(list[i], 'active');
}
}
}
MovimWebsocket.attach(function() {
Rooms.refresh();
});

1
app/widgets/Rooms/rooms.tpl

@ -0,0 +1 @@
<div id="rooms_widget">{$list}</div>

5
themes/material/css/style.css

@ -675,12 +675,13 @@ main section > div:first-child:nth-last-child(2) ~ div .actions.fixed > div:last
.placeholder.icon {
background-image: url(../img/placeholder/chat.png);
background-size: 25rem;
padding-top: 26rem;
padding-top: 27rem;
background-repeat: no-repeat;
background-position: center 1em;
background-position: center 4em;
}
.icon.newspaper { background-image: url(../img/icons/view_list.svg); }
.icon.forum { background-image: url(../img/icons/forum.svg); }
.icon.media { background-image: url(../img/placeholder/media.png); }
.icon.explore { background-image: url(../img/placeholder/explore.png); }
.icon.plane { background-image: url(../img/placeholder/plane.png); }

Loading…
Cancel
Save