Browse Source

- Continue the refactoring

- New flat design CSS + start of the mobile version
- Clean some olf CSS
pull/16/head
Jaussoin Timothée 13 years ago
parent
commit
980c138f18
  1. 5
      app/assets/documents/colors.txt
  2. 6
      app/assets/js/movim.js
  3. 71
      app/controllers/ControllerAjax.php
  4. 147
      app/controllers/ControllerBase.php
  5. 392
      app/controllers/ControllerMain.php
  6. 4
      app/widgets/.dir-locals.el
  7. 123
      app/widgets/About/About.php
  8. 488
      app/widgets/Account/Account.php
  9. 15
      app/widgets/Account/account.css
  10. 3
      app/widgets/Account/account.js
  11. 246
      app/widgets/Account/server-vcards.xml
  12. 484
      app/widgets/Admin/Admin.php
  13. 29
      app/widgets/Blog/Blog.php
  14. 280
      app/widgets/Bookmark/Bookmark.php
  15. 7
      app/widgets/Bookmark/bookmark.css
  16. 437
      app/widgets/Chat/Chat.php
  17. 181
      app/widgets/Chat/chat.css
  18. 102
      app/widgets/Chat/chat.js
  19. BIN
      app/widgets/Chat/img/arrow.png
  20. BIN
      app/widgets/Chat/img/cross.png
  21. BIN
      app/widgets/Chat/sound/notif.ogg
  22. 150
      app/widgets/ChatExt/ChatExt.php
  23. 0
      app/widgets/ChatExt/chatext.css
  24. 31
      app/widgets/ChatExt/chatext.js
  25. 45
      app/widgets/ChatPop/ChatPop.php
  26. 161
      app/widgets/ChatPop/chatpop.css
  27. 46
      app/widgets/ChatPop/chatpop.js
  28. BIN
      app/widgets/ChatPop/img/cross.png
  29. 196
      app/widgets/Config/Config.php
  30. BIN
      app/widgets/Config/color/arrow.gif
  31. BIN
      app/widgets/Config/color/cross.gif
  32. 12
      app/widgets/Config/color/demo.html
  33. BIN
      app/widgets/Config/color/hs.png
  34. BIN
      app/widgets/Config/color/hv.png
  35. 953
      app/widgets/Config/color/jscolor.js
  36. 0
      app/widgets/Config/config.css
  37. 104
      app/widgets/ConfigData/ConfigData.php
  38. 0
      app/widgets/ConfigData/configdata.css
  39. 143
      app/widgets/ContactCard/ContactCard.php
  40. 8
      app/widgets/ContactCard/contactcard.css
  41. 214
      app/widgets/ContactInfo/ContactInfo.php
  42. 83
      app/widgets/ContactManage/ContactManage.php
  43. 75
      app/widgets/ContactPubsubSubscription/ContactPubsubSubscription.php
  44. 104
      app/widgets/ContactSummary/ContactSummary.php
  45. 28
      app/widgets/ContactSummary/contactsummary.css
  46. 160
      app/widgets/Explore/Explore.php
  47. 4
      app/widgets/Explore/explore.css
  48. 213
      app/widgets/Feed/Feed.php
  49. 1
      app/widgets/Feed/feed.css
  50. 21
      app/widgets/Feed/feed.js
  51. 74
      app/widgets/Help/Help.php
  52. 0
      app/widgets/Help/help.css
  53. 49
      app/widgets/Log/Log.php
  54. 29
      app/widgets/Log/log.css
  55. 335
      app/widgets/Login/Login.php
  56. BIN
      app/widgets/Login/img/beaker.png
  57. BIN
      app/widgets/Login/img/envelope.png
  58. BIN
      app/widgets/Login/img/facebook.png
  59. BIN
      app/widgets/Login/img/jabber.png
  60. BIN
      app/widgets/Login/img/logo.png
  61. 512
      app/widgets/Login/img/logo.svg
  62. 238
      app/widgets/Login/img/logo2.svg
  63. 155
      app/widgets/Login/login.css
  64. 12
      app/widgets/Login/login.js
  65. 125
      app/widgets/Logout/Logout.php
  66. BIN
      app/widgets/Logout/img/away.png
  67. BIN
      app/widgets/Logout/img/dnd.png
  68. 0
      app/widgets/Logout/img/door_open.png
  69. BIN
      app/widgets/Logout/img/online.png
  70. BIN
      app/widgets/Logout/img/xa.png
  71. 60
      app/widgets/Logout/logout.css
  72. 9
      app/widgets/Logout/logout.js
  73. 158
      app/widgets/Media/Media.php
  74. BIN
      app/widgets/Media/img/paper.png
  75. 115
      app/widgets/Media/media.css
  76. 181
      app/widgets/Media/media.js
  77. 86
      app/widgets/MediaUpload/MediaUpload.php
  78. 28
      app/widgets/MediaUpload/mediaupload.css
  79. 240
      app/widgets/Node/Node.php
  80. 103
      app/widgets/NodeAffiliations/NodeAffiliations.php
  81. 119
      app/widgets/NodeConfig/NodeConfig.php
  82. 51
      app/widgets/Notification/Notification.php
  83. BIN
      app/widgets/Notification/img/error.png
  84. BIN
      app/widgets/Notification/img/info.png
  85. BIN
      app/widgets/Notification/img/success.png
  86. BIN
      app/widgets/Notification/img/warning.png
  87. 71
      app/widgets/Notification/notification.css
  88. 21
      app/widgets/Notification/notification.js
  89. 290
      app/widgets/Notifs/Notifs.php
  90. 134
      app/widgets/Notifs/notifs.css
  91. 64
      app/widgets/Notifs/notifs.js
  92. 35
      app/widgets/Poller/Poller.php
  93. 70
      app/widgets/Poller/poller.js
  94. 144
      app/widgets/Profile/Profile.php
  95. 47
      app/widgets/Profile/profile.css
  96. 13
      app/widgets/Profile/profile.js
  97. 123
      app/widgets/ProfileData/ProfileData.php
  98. 61
      app/widgets/ProfileData/profiledata.js
  99. 83
      app/widgets/PubsubSubscriptionConfig/PubsubSubscriptionConfig.php
  100. 402
      app/widgets/Roster/Roster.php

5
app/assets/documents/colors.txt

@ -0,0 +1,5 @@
red : #D92727
orange : #FC8F12
yellow : #FFE433
green : #6FCC43
blue : #0DB8B5

6
app/assets/js/movim.js

@ -148,11 +148,11 @@ function getFeedMessage() {
}
function frameHeight(n, text) {
if(n.className == 'button tiny icon alone add merged') {
n.className = 'button tiny icon alone rm merged';
if(n.className == 'button icon color alone add merged') {
n.className = 'button icon color alone rm merged';
text.style.minHeight = '20em';
} else {
n.className = 'button tiny icon alone add merged';
n.className = 'button icon color alone add merged';
text.style.minHeight = '1.5em';
}
}

71
app/controllers/ControllerAjax.php

@ -0,0 +1,71 @@
<?php
/**
* @file ControllerAjax.php
* This file is part of PROJECT.
*
* @brief Description
*
* @author Guillaume Pasquet <email@addre.ss>
*
* @version 1.0
* @date 8 November 2010
*
* Copyright (C)2010 PROPRIETOR
*
* OTHER T&C IF ANY
*/
class ControllerAjax extends ControllerBase
{
protected $funclist = array();
protected static $instance;
public function __construct()
{
parent::__construct();
}
public static function getInstance()
{
if(!is_object(self::$instance)) {
self::$instance = new ControllerAjax();
}
return self::$instance;
}
/**
* Generates the javascript part of the ajax.
*/
public function genJs()
{
if(empty($this->funclist)) {
return '';
}
$buffer = '<script type="text/javascript">';
foreach($this->funclist as $funcdef) {
$parlist = implode(', ', $funcdef['params']);
$buffer .= "function " . $funcdef['object'] . '_'
. $funcdef['funcname'] . "(${parlist}) {";
$buffer .= "movim_ajaxSend('".$funcdef['object']."', '".$funcdef['funcname']."', [${parlist}]);}\n";
}
return $buffer . "</script>\n";
}
/**
* Defines a new function.
*/
public function defun($widget, $funcname, array $params)
{
$this->funclist[] = array(
'object' => $widget,
'funcname' => $funcname,
'params' => $params,
);
}
}
?>

147
app/controllers/ControllerBase.php

@ -0,0 +1,147 @@
<?php
/**
* @file Controller.php
* This file is part of MOVIM.
*
* @brief Implements a request handler that ensures application worklfow.
*
* @author Movim Project <movim@movim.eu>
*
* @version 1.0
* @date 13 October 2010
*
* Copyright (C)2010 Movim Project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
class ControllerBase
{
protected $default_handler = 'index';
protected $token;
public function __construct($token = 'q')
{
$this->load_language();
$this->token = $token;
}
public function handle()
{
$r = new Route();
// Note that the request is always specified by 'q'.
$request;
if($request = $this->fetch_get('q')) {
$this->run_req($request);
} else {
$this->run_req($this->default_handler);
}
}
/**
* Loads up the language, either from the User or default.
*/
function load_language() {
$user = new user();
if($user->isLogged()) {
try{
$lang = $user->getConfig('language');
load_language($lang);
}
catch(MovimException $e) {
// Load default language.
load_language(Conf::getServerConfElement('defLang'));
}
}
else if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
load_language_auto();
}
else {
load_language(Conf::getServerConfElement('defLang'));
}
}
/**
* Attempts to call back the given function.
*/
protected function run_req($request)
{
if(is_callable(array($this, $request))) {
call_user_func(array($this, $request));
} else {
$this->error404();
}
}
/**
* Returns the value of a $_GET variable. Mainly used to avoid getting
* notices from PHP when attempting to fetch an empty variable.
* @param name is the desired variable's name.
* @return the value of the requested variable, or FALSE.
*/
protected function fetch_get($name)
{
if(isset($_GET[$name])) {
return htmlentities($_GET[$name]);
} else {
return false;
}
}
/**
* Returns the value of a $_POST variable. Mainly used to avoid getting
* notices from PHP when attempting to fetch an empty variable.
* @param name is the desired variable's name.
* @return the value of the requested variable, or FALSE.
*/
protected function fetch_post($name)
{
if(isset($_POST[$name])) {
return htmlentities($_POST[$name]);
} else {
return false;
}
}
/**
* Return a basic auth page for the administration area
*/
protected function authenticate(){
header('WWW-Authenticate: Basic realm="Enter admin username/password"');
header('HTTP/1.0 401 Unauthorized');
echo 'Why are you hitting cancel?';
exit;
}
/**
* Makes an error 404 page.
*/
protected function error404()
{
//echo 'Error 404 - Page not found';
$page = new TplPageBuilder();
$page->setTitle(t('%s - 404', APP_TITLE));
$page->menuAddLink(t('Home'), 'main', true);
$content = new TplPageBuilder();
$page->setContent($content->build('404.tpl'));
echo $page->build('page.tpl');
}
}
?>

392
app/controllers/ControllerMain.php

@ -0,0 +1,392 @@
<?php
/**
* @file ControllerMain.php
* This file is part of MOVIM.
*
* @brief Handles incoming static pages requests.
*
* @author Etenil <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 21 October 2010
*
* Copyright (C)2010 MOVIM Project
*
* See COPYING for licensing deatils.
*/
class ControllerMain extends ControllerBase
{
protected $default_handler = 'main';
private $page;
function __construct()
{
parent::__construct();
$this->page = new TplPageBuilder();
$this->page->addScript('movim.js');
$this->page->addScript('hash.js');
$this->page->addScript('movimrpc.js');
}
function main()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Welcome to Movim', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main', true);
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('main.tpl'));
echo $this->page->build('page.tpl');
}
}
function friend()
{
$user = new User();
$cd = new \modl\ContactDAO();
$contact = $cd->get($_GET['f']);
if(isset($contact))
$name = $contact->getTrueName();
else
$name = $_GET['f'];
if(!$user->isLogged()) {
$this->login();
} else {
if(isset($_GET['f']) && $_GET['f'] != "" ) {
$this->page->setTitle(APP_TITLE.' - '.$name);
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('friend.tpl'));
echo $this->page->build('page.tpl');
}
else
$this->main();
}
}
function server()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
if(isset($_GET['s']) && $_GET['s'] != "" ) {
$this->page->setTitle(APP_TITLE.' - Server');
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('server.tpl'));
echo $this->page->build('page.tpl');
}
else
$this->main();
}
}
function node()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
if(isset($_GET['n']) && $_GET['n'] != "" ) {
$this->page->setTitle(APP_TITLE.' - Node');
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('node.tpl'));
echo $this->page->build('page.tpl');
}
else
$this->main();
}
}
function media()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(APP_TITLE.' - Node');
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media', true);
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('media.tpl'));
echo $this->page->build('page.tpl');
}
}
function conf()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Configuration', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf', true);
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('conf.tpl'));
echo $this->page->build('page.tpl');
}
}
function profile()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Profile', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile', true);
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('profile.tpl'));
echo $this->page->build('page.tpl');
}
}
function account()
{
$this->page->setTitle(t('%s - Account', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Account Creation'), 'account', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('account.tpl'));
echo $this->page->build('page.tpl');
}
function blog()
{
$this->page->setTitle(t('%s - Account', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Blog'), 'blog', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('blog.tpl'));
echo $this->page->build('page.tpl');
}
function about()
{
$this->page->setTitle(t('%s - About', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('About'), 'about', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('about.tpl'));
echo $this->page->build('page.tpl');
}
function chatpop()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
echo $this->page->build('chatpop.tpl');
}
}
function post()
{
$user = new User();
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->setTitle(t('%s - Post View', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('post.tpl'));
echo $this->page->build('page.tpl');
}
}
/**
* Show login interface
*/
function login()
{
$this->page->setTitle(t('%s - Login to Movim', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main', true);
$this->page->menuAddLink(t('About'), 'about');
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('login.tpl'));
echo $this->page->build('page.tpl');
}
/**
* Create the Atom feed of a user
*/
function feed()
{
$content = new TplPageBuilder();
echo $content->build('feed.tpl');
}
/**
* Explore the XMPP network
*/
function explore()
{
$user = new User();
$this->page->setTitle(t('%s - Explore', APP_TITLE));
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore', true);
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help');
$this->page->menuAddLink(t('Logout'), 'disconnect');
}
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('explore.tpl'));
echo $this->page->build('page.tpl');
}
/*
* Show help page
*/
function help()
{
$user = new User();
$this->page->setTitle(t('%s - Help Page', APP_TITLE));
if(!$user->isLogged()) {
$this->login();
} else {
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Explore'), 'explore');
$this->page->menuAddLink(t('Profile'), 'profile');
$this->page->menuAddLink(t('Media'), 'media');
$this->page->menuAddLink(t('Configuration'), 'conf');
$this->page->menuAddLink(t('Help'), 'help', true);
$this->page->menuAddLink(t('Logout'), 'disconnect');
}
$content = new TplPageBuilder($user);
$this->page->setContent($content->build('help.tpl'));
echo $this->page->build('page.tpl');
}
/*
* Show admin page
*/
function admin()
{
error_reporting(0);
if(!isset($_SERVER['PHP_AUTH_USER'])) {
$this->authenticate();
} else {
$conf = Conf::getServerConf();
if($_SERVER['PHP_AUTH_USER'] == (string)$conf['user'] && sha1($_SERVER['PHP_AUTH_PW']) == (string)$conf['pass']){
$this->page->setTitle(t('%s - Administration Panel', APP_TITLE));
$this->page->menuAddLink(t('Home'), 'main');
$this->page->menuAddLink(t('Administration'), 'admin', true);
$content = new TplPageBuilder();
$this->page->setContent($content->build('admin.tpl'));
echo $this->page->build('page.tpl');
} else {
$this->authenticate();
}
}
}
function disconnect()
{
$user = new User();
$user->desauth();
$this->login();
}
}

4
app/widgets/.dir-locals.el

@ -0,0 +1,4 @@
((nil . ((indent-tabs-mode . nil)
(tab-width . 4)
(fill-column . 80)))
(c-mode . ((c-file-style . "stroustrup"))))

123
app/widgets/About/About.php

@ -0,0 +1,123 @@
<?php
/**
* @package Widgets
*
* @file Vcard.php
* This file is part of MOVIM.
*
* @brief A widget which display some help
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 3 may 2012
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class About extends WidgetBase
{
function WidgetLoad() {
}
function build()
{
?>
<div class="tabelem padded" title="<?php echo t('About'); ?>" id="about">
<p>Movim is an XMPP-based communication platform. All the project, except the following software and resources, is under
<a href="http://www.gnu.org/licenses/agpl-3.0.html">GNU Affero General Public License v3</a>.
</p>
<h2><?php echo t('Thanks'); ?></h2>
<dl>
<dt>Developers</dt><dd><a href="http://edhelas.mov.im/">Jaussoin Timothée aka edhelas</a></dd>
<dt></dt><dd><a href="https://launchpad.net/~nodpounod">Ho Christine aka nodpounod</a></dd>
<dt></dt><dd><a href="https://etenil.net/">Pasquet Guillaume aka Etenil</a></dd>
<dt>Translators</dt><dd>Arabic - <a href="https://launchpad.net/~gharbeia">Ahmad Gharbeia أحمد غربية</a></dd>
<dt></dt><dd>Brazilian - <a href="https://launchpad.net/~dnieper650">millemiglia</a></dd>
<dt></dt><dd>Chinese - <a href="https://launchpad.net/~dudumomo">dudumomo</a></dd>
<dt></dt><dd>Danish - <a href="https://launchpad.net/~ole-carlsen-web">Ole Carlsen</a></dd>
<dt></dt><dd>Dutch - <a href="https://launchpad.net/~laurens-debackere">Laurens Debackere</a></dd>
<dt></dt><dd>English UK - <a href="https://launchpad.net/~kevinbeynon">Kevin Beynon</a>, <a href="https://launchpad.net/~influence-pc">Vincent</a></dd>
<dt></dt><dd>Esperanto - <a href="https://launchpad.net/~eliovir">Eliovir</a></dd>
<dt></dt><dd>Finish - <a href="https://launchpad.net/~e1484180">Timo</a></dd>
<dt></dt><dd>French -
<a href="https://launchpad.net/~hyogapag">Hyogapag</a>,
<a href="https://launchpad.net/~e1484180">Hélion du Mas des Bourboux</a>,
<a href="https://launchpad.net/~jonathanmm">JonathanMM</a>,
<a href="https://launchpad.net/~grossard-o">Ludovic Grossard</a>,
<a href="https://launchpad.net/~schoewilliam">Schoewilliam</a>,
<a href="https://launchpad.net/~influence-pc">Vincent</a>,
<a href="https://launchpad.net/~edhelas">edhelas</a>,
<a href="https://launchpad.net/~nodpounod">pou</a>
</dd>
<dt></dt><dd>German -
<a href="https://launchpad.net/~q-d">Daniel Winzen</a>,
<a href="https://launchpad.net/~jonas-ehrhard">Jonas Ehrhard</a>,
<a href="https://launchpad.net/~jonatan-zeidler-gmx">Jonatan Zeidler</a>,
<a href="https://launchpad.net/~kili4n">Kilian Holzinger</a>,
</dd>
<dt></dt><dd>Greek -
<a href="https://launchpad.net/~d-rotarou">Rotaru Dorin</a>,
<a href="https://launchpad.net/~yang-hellug">aitolos</a>
</dd>
<dt></dt><dd>Hebrew - <a href="https://launchpad.net/~genghiskhan">GenghisKhan</a></dd>
<dt></dt><dd>Hungarian - <a href="https://launchpad.net/~batisteo">Baptiste Darthenay</a></dd>
<dt></dt><dd>Italian -
<a href="https://launchpad.net/~andrea-caratti-phys">Andrea Caratti</a>,
<a href="https://launchpad.net/~giacomo-alzetta">Giacomo Alzetta</a>,
<a href="https://launchpad.net/~emailadhoc">kimj</a>
</dd>
<dt></dt><dd>Japanese - <a href="https://launchpad.net/~fdelbrayelle">Franky</a></dd>
<dt></dt><dd>Occitan (post 1500) -
<a href="https://launchpad.net/~cvalmary">Cédric VALMARY (Tot en òc)</a>,
<a href="https://launchpad.net/~caillonm">Maime</a>
</dd>
<dt></dt><dd>Portuguese -
<a href="https://launchpad.net/~jonathanmm">JonathanMM</a>,
<a href="https://launchpad.net/~dnieper650">millemiglia</a>
</dd>
<dt></dt><dd>Russian -
<a href="https://launchpad.net/~ak099">Aleksey Kabanov</a>,
<a href="https://launchpad.net/~vsharmanov">Vyacheslav Sharmanov</a>,
<a href="https://launchpad.net/~hailaga">hailaga</a>,
<a href="https://launchpad.net/~salnsg">Сергей Сальников</a>,
<a href="https://launchpad.net/~mr-filinkov">DeforaD</a>
</dd>
<dt></dt><dd>Spanish -
<a href="https://launchpad.net/~alejandrosg">Alejandro Serrano González</a>,
<a href="https://launchpad.net/~edu5800">Eduardo Alberto Calvo</a>,
<a href="https://launchpad.net/~estebanmainieri">Esteban Mainieri</a>,
<a href="https://launchpad.net/~victormezio">Oizem Mushroom</a>,
<a href="https://launchpad.net/~kaiser-715-deactivatedaccount">Ricardo Sánchez Baamonde</a>,
<a href="https://launchpad.net/~invrom">Ubuntu</a>,
<a href="https://launchpad.net/~orochiforja">orochiforja</a>
</dd>
<dt></dt><dd>Turkish -
<a href="https://launchpad.net/~basaran-caner">Caner Başaran</a>,
<a href="https://launchpad.net/~emreakca">emre akça</a>
</dd>
</dl>
<h2><?php echo t('Software'); ?></h2>
<dl>
<dt>Database Library</dt><dd>Modl - Movim DB Layer <a href="https://launchpad.net/modl">launchpad.net/modl</a> under AGPLv3</dd>
<dt>XMPP Library</dt><dd>Moxl - Movim XMPP Library <a href="https://launchpad.net/moxl">launchpad.net/moxl</a> under AGPLv3</dd>
</dl>
<br />
<dl>
<dt>Map Library</dt><dd>Leaflet <a href="http://leafletjs.com/">leafletjs.com</a> under BSD</dd>
<dt>Markdown</dt><dd>Michel Fortin <a href="http://michelf.ca/projects/php-markdown/">michelf.ca</a> ©Michel Fortin</dd>
<dt>HTML Fixer</dt><dd> Giulio Pons <a href="http://www.barattalo.it">barattalo.it</a></dd>
</dl>
<h2><?php echo t('Ressources'); ?></h2>
<dl>
<dt>Icons</dt><dd>Famfamfam <a href="http://www.famfamfam.com/">www.famfamfam.com</a> under CC BY 3.0</dd>
<dt></dt><dd>Icomoon <a href="http://keyamoon.com/">by Keyamoon</a> under CC BY 3.0</dd>
</dl>
</div>
<?php
}
}

488
app/widgets/Account/Account.php

@ -0,0 +1,488 @@
<?php
/**
* @package Widgets
*
* @file Account.php
* This file is part of MOVIM.
*
* @brief The account creation widget.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 25 November 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Account extends WidgetBase {
function WidgetLoad()
{
$this->addcss('account.css');
$this->addjs('account.js');
}
function ajaxDiscoverServer($ndd) {
if($ndd['ndd'] == '') {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=datamissing");
RPC::commit();
exit;
}
try {
$dns = dns_get_record('_xmpp-client._tcp.'.$ndd['ndd']);
if(isset($dns[0]['target']) && $dns[0]['target'] != null)
$domain = $dns[0]['target'];
$f = fsockopen($domain, 5222, $errno, $errstr, 10);
if(!$f) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppconnect");
RPC::commit();
exit;
}
$stream = simplexml_load_string('<?xml version="1.0"?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0"><iq type="get" id="reg1"><query xmlns="jabber:iq:register"/></iq></stream:stream>');
$stream->addAttribute('to', $ndd['ndd']);
fwrite($f, $stream->asXML());
unset($stream);
$response = stream_get_contents($f);
if(!$response) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppcomm");
RPC::commit();
exit;
}
$response = simplexml_load_string($response);
$id = (string)$response->attributes()->id;
$elements = (array)$response->iq->query;
// We close properly our first register request
$stream = simplexml_load_string('<?xml version="1.0"?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0"><iq type="set" id="unreg1"><query xmlns="jabber:iq:register"><remove/></query></iq></stream:stream>');
$stream->addAttribute('to', $ndd['ndd']);
fwrite($f, $stream->asXML());
fclose($f); unset($f);
if(!empty($elements)) {
$html .= '
<form name="data">
<fieldset>
<legend>'.t('Step 2 - Fill in your informations').'</legend><br /><br /><br />';
if($response->iq->query->instructions && $response->iq->query->x) {
$instr = '
<div class="element simple large">
<label>'.(string)$response->iq->query->instructions.'</label>';
if($response->iq->query->x->url)
$instr .= '
<a href="'.(string)$response->iq->query->x->url.'" target="_blank">'.
(string)$response->iq->query->x->url.'
</a>';
$instr .= '
</div>';
}
$form = new XMPPtoForm();
if(!empty($response->iq->query->x)){
$formh .= $form->getHTML($response->iq->query->x->asXML());
} else{/*no <x> element in the XML*/
$formh .= $form->getHTML($response->iq->query->asXML());
}
if($formh == '')
$html .= $instr;
else
$html .= $formh;
$html .= '
<input
type="hidden"
value="'.$domain.'"
name="ndd"
id="ndd"
/>
';
$html .= '
<input
type="hidden"
value="'.$ndd['ndd'].'"
name="to"
id="to"
/>
';
$html .= '
<input
type="hidden"
value="'.$id.'"
name="id"
id="id"
/>
';
if(isset($elements['data'])) {
$html .= '<img src="data:image/jpg;base64,'.$elements['data'].'"/>';
}
$submit = $this->genCallAjax('ajaxSubmitData', "movim_parse_form('data')");
$html .= '
<a
class="button color green icon yes"
style="float: right;"
onclick="'.$submit.'"
>
'.t('Validate').'
</a>';
$html .= '
</fieldset>
</form>';
RPC::call('movim_fill', 'fillform', $html);
RPC::commit();
}
else {
$html = '
<div class="message warning">
'.t('No account creation form founded on the server').'
</div>';
RPC::call('movim_fill', 'fillform', $html);
RPC::commit();
}
} catch(Exception $e) {
header(sprintf('HTTP/1.1 %d %s', $e->getCode(), $e->getMessage()));
header('Content-Type: text/plain; charset=utf-8');
echo $e->getMessage(),"\n";
}
}
function ajaxSubmitData($datas) {
define(XMPP_HOST, $datas['to']);
define(XMPP_CONN, $datas['ndd']);
unset($datas['to']);
unset($datas['ndd']);
//unset($datas['id']);
define(XMPP_PORT, 5222);
try {
// We try to connect to the XMPP Server
$f = fsockopen(XMPP_CONN, XMPP_PORT, $errno, $errstr, 10);
if(!$f) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppconnect");
RPC::commit();
exit;
}
// We create the XML Stanza
$stream = simplexml_load_string('<?xml version="1.0"?><stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" version="1.0"><iq id="'.$datas['id'].'" type="set"><query xmlns="jabber:iq:register"></query></iq></stream:stream>');
unset($datas['id']);
$stream->addAttribute('to', XMPP_HOST);
$xmpp = new FormtoXMPP();
$stream = $xmpp->getXMPP($stream->asXML(), $datas);
\movim_log($stream->asXML());
fwrite($f, $stream->asXML());
unset($stream);
$response = stream_get_contents($f);
if(!$response) {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=xmppcomm");
RPC::commit();
exit;
}
fclose($f); unset($f);
$response = simplexml_load_string($response);
\movim_log($response);
if(!$response) throw new Exception('The XMPP server sent an invalid response', 500);
if($stream_error = $response->xpath('/stream:stream/stream:error')) {
list($stream_error) = $stream_error;
list($cond) = $stream_error->children();
throw new Exception($stream_error->text ? $stream_error->text : $cond->getName(), 500);
}
$iq = $response->iq;
if($iq->error) {
list($cond) = $iq->error->children();
if($cond->getName() == 'conflict') {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=userconflict");
RPC::commit();
exit;
} else if($cond->getName() == 'not-acceptable') {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=notacceptable");
RPC::commit();
exit;
}
throw new Exception($iq->error->text ? $iq->error->text : $cond->getName(), 400);
}
if($iq = $response->iq and $iq->attributes()->type == 'result') {
RPC::call('movim_reload', BASE_URI."index.php?q=login&err=acccreated");
RPC::commit();
exit;
} else {
RPC::call('movim_reload', BASE_URI."index.php?q=account&err=unknown");
RPC::commit();
exit;
}
} catch(Exception $e) {
header(sprintf('HTTP/1.1 %d %s', $e->getCode(), $e->getMessage()));
header('Content-Type: text/plain; charset=utf-8');
echo $e->getMessage(),"\n";
}
}
function printServerList() {
$file = dirname(__FILE__).DIRECTORY_SEPARATOR.'server-vcards.xml';
$html = '';
if(file_exists($file)) {
$vcards = simplexml_load_file($file);
$html .= '
<div class="clear"></div>
<table id="list">
<thead>
<tr>
<td>
'.t('Name').'
</td>
<td>
'.t('Description').'
</td>
<td>
'.t('URL').'
</td>
<td>
'.t('Software').'
</td>
<td>
</td>
</tr>
</thead>
<tbody>';
$markers = array();
foreach($vcards as $vcard) {
$name = (string)$vcard->fn->text;
$html .='
<tr onclick="selectServer(\''.$name.'\');">
<td>
<a href="#nddlink">'.$name.'</a>
</td>
<td>
'.(string)$vcard->note->text.'
</td>
<td>
<a target="_blank" href="'.(string)$vcard->url->uri.'">
'.(string)$vcard->url->uri.'
</a>
</td>
<td>
'.(string)$vcard->name.'
</td>
<td>
<img
title="'.(string)$vcard->adr->country.'"
alt="'.(string)$vcard->adr->country.'"
src="'.BASE_URI.'themes/movim/img/flags/'.strtolower((string)$vcard->adr->country).'.png"/>
</td>
</tr>
';
$coord = explode("geo:", $vcard->geo->uri);
if(isset($coord[1])){
$split = explode(",", $coord[1]);
$newkey = round(floatval($split[0]),1).",".round(floatval($split[1]),1);
if(!isset($markers[$newkey])){
$markers[$newkey] = array($name);
}
else{
array_push($markers[$newkey], $name);
}
}
}
$html .= '
</tbody>
</table>';
$javascript = '<script type="text/javascript">
var map = L.map("map").setView([40,0], 2);
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "Map data &copy; <a href=\"http://openstreetmap.org\">OpenStreetMap</a> contributors, <a href=\"http://creativecommons.org/licenses/by-sa/2.0/\">CC-BY-SA</a>, Mapnik ©",
maxZoom: 18
}).addTo(map);';
$id = 0;
foreach($markers as $coord => $arrayOfNames){
$javascript .= "
var marker".$id." = L.marker([".$coord."]).addTo(map);
marker".$id.".bindPopup('";
foreach($arrayOfNames as $name){
$action = 'selectServer("'.$name.'");';
$javascript .= "<span onclick=\'".$action."\' ><a href=\'#nddlink\'>".$name."</a></span><br />";
}
$javascript .= "');
";
$id++;
}
$javascript .= '</script>';
}
return $javascript.$html;
}
function build()
{
switch ($_GET['err']) {
case 'datamissing':
$warning = '
<div class="message error">
'.t('Some data are missing !').'
</div> ';
break;
case 'jiderror':
$warning = '
<div class="message error">
'.t('Wrong ID').'
</div> ';
break;
case 'passworddiff':
$warning = '
<div class="message error">
'.t('You entered different passwords').'
</div> ';
break;
case 'nameerr':
$warning = '
<div class="message error">
'.t('Invalid name').'
</div> ';
break;
case 'notacceptable':
$warning = '
<div class="message error">
'.t('Request not acceptable').'
</div> ';
break;
case 'userconflict':
$warning = '
<div class="message error">
'.t('Username already taken').'
</div> ';
break;
case 'xmppconnect':
$warning = '
<div class="message error">
'.t('Could not connect to the XMPP server').'
</div> ';
break;
case 'xmppcomm':
$warning = '
<div class="message error">
'.t('Could not communicate with the XMPP server').'
</div> ';
break;
case 'unknown':
$warning = '
<div class="message error">
'.t('Unknown error').'
</div> ';
break;
}
$submit = $this->genCallAjax('ajaxDiscoverServer', "movim_parse_form('account')");
?>
<div id="main">
<div id="left">
<?php echo $warning; ?>
</div>
<div id="center">
<h1><?php echo t('Create a new account'); ?></h1>
<div style="margin: 15px 20px;">
<p>
<?php echo t('Movim is a decentralized social network, before creating a new account you need to choose a server to register.'); ?>
<?php echo t('Keep in mind that this server will handle all your personnal data.'); ?>
</p>
<br />
<form name="account">
<fieldset>
<legend><?php echo t('Step 1 - Search the server'); ?></legend>
<div class="clear"></div>
<p>
<?php echo t('You can%s enter your server domain name%s. ', '<a href="#nddlink">', '</a>');
echo t('Or you can choose a server from this list.'); ?>
</p>
<br />
<div style="height: 300px;" id="map"></div>
<br />
<?php echo $this->printServerList(); ?>
<br />
<div class="element">
<label for="ndd"><?php echo t("Server"); ?></label>
<input
pattern="^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$"
placeholder="<?php echo t("Enter the server domain (ex: movim.eu)"); ?>"
name="ndd"
id="ndd"
/>
</div>
<div class="clear"></div>
<a
name="nddlink"
class="button icon search color green"
style="float: right;"
onclick="<?php echo $submit;?>; document.getElementById('fillform').innerHTML ='<?php echo t('Searching...');?>'"
>
<?php echo t('Search'); ?>
</a>
</form>
<div class="clear"></div>
<div id="fillform"></div>
</div>
</div>
</div>
<?php
}
}

15
app/widgets/Account/account.css

@ -0,0 +1,15 @@
#left {
padding-top: 0px !important;
margin-top: 1em !important;
}
#nav .menu li:last-child {
background-image: none;
padding-right: 0px;
position: relative;
}
table#list {
border-spacing:0;
border-collapse:collapse;
}

3
app/widgets/Account/account.js

@ -0,0 +1,3 @@
function selectServer(ndd) {
document.querySelector('input[name="ndd"]').value = ndd;
}

246
app/widgets/Account/server-vcards.xml

@ -0,0 +1,246 @@
<vcards>
<vcard>
<fn>
<text>movim.eu</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://movim.eu/</uri>
</url>
<note>
<text>The Movim XMPP service.</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:movim.eu</uri>
</registration>
<bday>
<date>2013</date>
</bday>
<adr>
<country>IE</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>CAcert</name>
<uri>http://www.cacert.org/</uri>
</ca>
<name xmlns="jabber:iq:version">Metronome</name>
<impp>
<uri>xmpp:edhelas@movim.eu</uri>
</impp>
<geo>
<uri>geo:53.06,-7.29</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>jappix.com</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://jappix.com/</uri>
</url>
<note>
<text>The Jappix XMPP service.</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:jappix.com</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>FR</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>CAcert</name>
<uri>http://www.cacert.org/</uri>
</ca>
<name xmlns="jabber:iq:version">Metronome</name>
<impp>
<uri>xmpp:vanaryon@jappix.com</uri>
</impp>
<geo>
<uri>geo:50.67,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>tigase.im</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.tigase.im/</uri>
</url>
<note>
<text>The public Tigase service. - Also supports IPv6!</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:tigase.im</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>EU</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name xmlns="jabber:iq:version">Tigase</name>
<impp>
<uri>xmpp:admin@im.flosoft.biz</uri>
</impp>
<geo>
<uri>geo:50.69,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>lightwitch.org</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.lightwitch.org/</uri>
</url>
<note>
<text>LW.Org XMPP Public Service.</text>
</note>
<registration>
<uri>xmpp:lightwitch.org</uri>
</registration>
<bday>
<date>2009</date>
</bday>
<adr>
<country>USA</country>
</adr>
<ca>
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name>Metronome</name>
<impp>
<uri>xmpp:maranda@lightwitch.org</uri>
</impp>
<geo>
<uri>geo:40.73,-74.17</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>jabber.me</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.jabber.me/</uri>
</url>
<note>
<text>Just Jabber Me! - Also supports IPv6!</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:jabber.me</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>EU</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name xmlns="jabber:iq:version">Tigase</name>
<impp>
<uri>xmpp:admin@im.flosoft.biz</uri>
</impp>
<geo>
<uri>geo:50.69,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>sure.im</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.sure.im/</uri>
</url>
<note>
<text>Just Sure Im! - Also supports IPv6!</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:sure.im</uri>
</registration>
<bday>
<date>2010</date>
</bday>
<adr>
<country>EU</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>StartSSL</name>
<uri>http://www.startssl.com/</uri>
</ca>
<name xmlns="jabber:iq:version">Tigase</name>
<impp>
<uri>xmpp:admin@im.flosoft.biz</uri>
</impp>
<geo>
<uri>geo:50.69,3.19</uri>
</geo>
</vcard>
<vcard>
<fn>
<text>jabbim.cz</text>
</fn>
<kind>
<text>application</text>
</kind>
<url>
<uri>http://www.jabbim.cz/</uri>
</url>
<note>
<text>Stable ejabberd clustered server with good support and many transports and services: ICQ, AIM, MSN, Facebook, Weather, Yahoo, Notes, bots, MUCs, proxy65, STUN server for voice support, and more</text>
</note>
<registration xmlns="urn:xmpp:vcard:registration:1">
<uri>xmpp:jabbim.cz</uri>
</registration>
<bday>
<date>2005</date>
</bday>
<adr>
<country>CZ</country>
</adr>
<ca xmlns="urn:xmpp:vcard:ca:0">
<name>CAcert</name>
<uri>http://www.cacert.org/</uri>
</ca>
<name xmlns="jabber:iq:version">ejabberd</name>
<impp>
<uri>xmpp:pinky@njs.netlab.cz</uri>
</impp>
</vcard>
<vcard><fn><text>njs.netlab.cz</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:njs.netlab.cz</uri></registration><bday><date>2001</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>jabbim.pl</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:jabbim.pl</uri></registration><bday><date>2005</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>jabbim.sk</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:jabbim.sk</uri></registration><bday><date>2005</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>jabbim.com</text></fn><kind><text>application</text></kind><url><uri>http://www.jabbim.cz/</uri></url><note><text>Public service hosted by jabbim.cz</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:jabbim.com</uri></registration><bday><date>2005</date></bday><adr><country>CZ</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>CAcert</name><uri>http://www.cacert.org/</uri></ca><name xmlns="jabber:iq:version">ejabberd</name><impp><uri>xmpp:pinky@njs.netlab.cz</uri></impp></vcard>
<vcard><fn><text>forumanalogue.fr</text></fn><kind><text>application</text></kind><url><uri>http://www.forumanalogue.fr/</uri></url><note><text>A public self-hosted Jabber server located in France.</text></note><registration xmlns="urn:xmpp:vcard:registration:1"><uri>xmpp:forumanalogue.fr</uri></registration><bday><date>2010</date></bday><adr><country>FR</country></adr><ca xmlns="urn:xmpp:vcard:ca:0"><name>StartSSL</name><uri>http://www.startssl.com/</uri></ca><name xmlns="jabber:iq:version">Openfire</name><impp><uri>xmpp:clement@forumanalogue.fr</uri></impp><geo><uri>geo:45.8,4.84</uri></geo><lang><parameters><pref>1</pref></parameters><language-tag>fr</language-tag></lang></vcard>
</vcards>

484
app/widgets/Admin/Admin.php

@ -0,0 +1,484 @@
<?php
/**
* @package Widgets
*
* @file Admin.php
* This file is part of MOVIM.
*
* @brief The administration widget.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 25 November 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Admin extends WidgetBase {
private $_conf;
function WidgetLoad()
{
$this->_conf = Conf::getServerConf();
}
private function isValid($what)
{
if($what)
return "message success";
else
return "message error";
}
private function testDir($dir){
return (file_exists($dir) && is_dir($dir) && is_writable($dir));
}
private function testFile($file) {
return (file_exists($file) && is_writable($file));
}
/*
* Create the dirs
*/
function createDirs(){
if(!file_exists(BASE_PATH.'cache') && !@mkdir(BASE_PATH.'cache')) {
echo t("Couldn't create directory '%s'.", 'cache');
return false;
}
if(!file_exists(BASE_PATH.'log') && !@mkdir(BASE_PATH.'log')) {
echo t("Couldn't create directory '%s'.", 'log');
return false;
}
if(!file_exists(BASE_PATH.'config') && !@mkdir(BASE_PATH.'config')) {
echo t("Couldn't create directory '%s'.", 'config');
return false;
}
}
private function listThemes()
{
$dir = opendir(BASE_PATH.'themes');
$themes = array();
while($theme = readdir($dir)) {
if(preg_match('/^\.+$/', $theme)
|| !is_dir(BASE_PATH.'themes/'.$theme)) {
continue;
}
$themes[$theme] = $theme;
}
return $themes;
}
private function listLangs()
{
$dir = opendir(BASE_PATH.'i18n');
$langs = array('en' => 'English');
$languages = get_lang_list();
while($lang = readdir($dir)) {
if(!preg_match('/\.po$/', $lang)) {
continue;
}
$lang = substr($lang, 0, strlen($lang) - 3);
$langs[$lang] = $languages[$lang];
}
return $langs;
}
function testBosh($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Fire !
$rs = array();
$rs['content'] = curl_exec($ch);
$rs['errno'] = curl_errno($ch);
$rs['errmsg'] = curl_error($ch);
$rs['header'] = curl_getinfo($ch);
if($rs['content'] != false && $rs['content'] != '') {
return true;
}
elseif($rs['errno'] != 0 || $rs['content'] == '') {
return false;
}
curl_close($ch);
}
public function ajaxAdminSubmit($form)
{
unset($form['']);
$empty = false;
if($form['pass'] == '' || !isset($form['pass'])) {
$form['pass'] = $this->_conf['pass'];
$form['repass'] = $this->_conf['pass'];
$empty = true;
}
if($form['pass'] == $form['repass']) {
unset($form['repass']);
if(!$empty)
$form['pass'] = sha1($form['pass']);
foreach($this->_conf as $key => $value) {
if(isset($form[$key]))
$this->_conf[$key] = $form[$key];
}
Conf::saveConfFile($this->_conf);
}
}
public function ajaxRecreateDatabase()
{
$pd = new \modl\PostnDAO();
$pd->create();
$nd = new \modl\NodeDAO();
$nd->create();
$cd = new \modl\ContactDAO();
$cd->create();
$cad = new \modl\CapsDAO();
$cad->create();
$prd = new \modl\PresenceDAO();
$prd->create();
$rd = new \modl\RosterLinkDAO();
$rd->create();
$sd = new \modl\SessionDAO();
$sd->create();
$cd = new \modl\CacheDAO();
$cd->create();
$md = new \modl\MessageDAO();
$md->create();
$cd = new \modl\SubscriptionDAO();
$cd->create();
$pr = new \modl\PrivacyDAO();
$pr->create();
}
private function prepareAdmin()
{
$submit = $this->genCallAjax('ajaxAdminSubmit', "movim_parse_form('admin')")
."this.className='button icon loading'; setTimeout(function() {location.reload(false)}, 2000);";
if($this->testDir(BASE_PATH))
$this->createDirs();
$html = '
<form name="admin" id="adminform">';
/*$html .= '
<fieldset>
<legend>'.t('General Informations').'</legend>';
$file = BASE_PATH.'VERSION';
if($f = fopen($file, 'r')){
$html .= '
<div class="element simple">
<label for="fn">'.t('Version').'</label>
<span>'.trim(fgets($f)).'</span>
</div>';
}
$html .= '
</fieldset>';*/
$html .= '
<fieldset>
<legend>'.t("Compatibility Check").'</legend>
<div class="clear"></div>';
$html .=
'<p>'.
t('Movim requires certain external components. Please install them before you can succeed:').
'</p><br />';
$html .= '
<div class="'.$this->isValid((version_compare(PHP_VERSION, '5.3.0') >= 0)).'">
'.t('Your PHP-Version: %s <br>Required: 5.3.0', PHP_VERSION).'
</div>
<div class="'.$this->isValid(extension_loaded('curl')).'">
'.t('CURL-Library').'
</div>
<div class="'.$this->isValid(extension_loaded('gd')).'">
'.t('GD').'
</div>
<div class="'.$this->isValid(extension_loaded('SimpleXml')).'">
'.t('SimpleXML').'
</div>
<div class="'.$this->isValid($this->testDir(BASE_PATH)).'">
'.t('Read and write rights for the webserver in Movim\'s root directory').'
</div>
<div class="'.$this->isValid($_SERVER['HTTP_MOD_REWRITE']).'">
'.t('URL Rewriting support').'
</div>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t('General Settings').'</legend>
<div class="element">
<label for="movim" >'.t('Theme').'</label>
<div class="select">
<select id="theme" name="theme">';
foreach($this->listThemes() as $key => $value) {
if((string)$this->_conf['theme'] == $key)
$sel = 'selected="selected"';
else
$sel = '';
$html .= '
<option value="'.$key.'" '.$sel.'>'.$value.'</option>';
}
$html .= ' </select>
</div>
</div>';
$html .= '
<div class="element">
<label for="da">'.t('Default language').'</label>
<div class="select">
<select id="defLang" name="defLang">';
foreach($this->listLangs() as $key => $value) {
if((string)$this->_conf['defLang'] == $key)
$sel = 'selected="selected"';
else
$sel = '';
$html .= '
<option value="'.$key.'" '.$sel.'>'.$value.'</option>';
}
$html .= ' </select>
</div>
</div>';
$html .= '
<div class="element">
<label for="maxUsers">'.t('Maximum population').'</label>
<input type="text" name="maxUsers" id="maxUsers" value="'.$this->_conf['maxUsers'].'" />
</div>';
$html .= '
<div class="element">
<label for="sizeLimit">'.t('User folder size limit (in bytes)').'</label>
<input type="text" name="sizeLimit" id="sizeLimit" value="'.$this->_conf['sizeLimit'].'" />
</div>';
$logopts = array(
0 => t('empty'),
2 => t('terse'),
4 => t('normal'),
6 => t('talkative'),
7 => t('ultimate'),
);
$default_log = 4;
$html .= '
<div class="element">
<label for="7">'.t("Log verbosity").'</label>
<div class="select">
<select id="logLevel" name="logLevel">';
foreach($logopts as $lognum => $text) {
if($this->_conf['logLevel'] == $lognum)
$sel = 'selected="selected"';
$html .= '
<option value="'.$lognum.'" '.$sel.'>'.
$text.'
</option>';
}
$html .= ' </select>
</div>
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Database Settings").'</legend>
<div class="clear"></div>';
$md = new \modl\ModlDAO();
if(isset($md->_dao->_error)) {
$html .= '
<div class="message error">'.
t("Modl wasn't able to connect to the database").'<br />
'.$md->_dao->_error.'
</div>
';
} else {
$dbrecreate = $this->genCallAjax('ajaxRecreateDatabase');
$html .= '
<div class="element">
<label for="db">'.t('Recreate the database').'</label>
<a class="button icon yes" onclick="'.$dbrecreate.'">'.t('Recreate').'</a>
</div>
<div class="message warning">
'.t('This button will clear and recreate the Movim database.').'
</div>
';
}
$html .= '
<div class="element large">
<label for="db">'.t('Dabase String').'</label>
<input type="text" name="db" id="db" value="'.$this->_conf['db'].'" />
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Bosh Configuration").'</legend>
<div class="clear"></div>';
$html .= '<p>'.
t("Enter here the BOSH-URL in the form: http(s)://domain:port/path.").' '.
t('If you enter an open BOSH-Server, you can connect to many XMPP-Servers.').' '.
t('If it is closed, you have to specify the corresponding Server on the next page.').' '.
t('If you are unsure about this config option visit the wiki');
'</p>';
if(!$this->testBosh($this->_conf['boshUrl'])) {
$html .= '
<div class="message error">'.
t('Your Bosh URL is not reachable').'
</div>';
}
$html .= '
<div class="element">
<label for="boshUrl">'.t("Bosh URL").'</label>
<input type="text" id="boshUrl" name="boshUrl" value="'.$this->_conf['boshUrl'].'"/>
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Whitelist - XMPP Server").'</legend>
<div class="clear"></div>';
$html .= '<p>'.
t("If you want to specify a list of authorized XMPP servers on your Movim pod and forbid the connection on all the others please put their domain name here, with comma (ex: movim.eu,jabber.fr)").
'</p>'.
'<p>'.
t("Leave this field blank if you allow the access to all the XMPP accounts.").
'</p>';
$html .= '
<div class="element large">
<label for="xmppWhiteList">'.t("List of whitelisted XMPP servers").'</label>
<input type="text" name="xmppWhiteList" id="xmppWhiteList" value="'.$this->_conf['xmppWhiteList'].'" />
</div>';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
<fieldset>
<legend>'.t("Administration Credential").'</legend>';
if($this->_conf['user'] == 'admin' && $this->_conf['pass'] == sha1('password')) {
$html .= '
<div class="message error">'.
t('Change the default username/password').'
</div>';
}
$html .= '
<div class="element" >
<label for="username">'.t("Username").'</label>
<input type="text" id="user" name="user" value="'.$this->_conf['user'].'"/>
</div>
<div class="clear"></div>
<div class="element">
<label for="pass">'.t("Password").'</label>
<input type="password" id="pass" name="pass" value=""/>
</div>
<div class="element">
<label for="repass">'.t("Retype password").'</label>
<input type="password" id="repass" name="repass" value=""/>
</div> ';
$html .= '
<div class="clear"></div>
<a class="button icon submit" style="float: right;" onclick="'.$submit.'">'.t('Submit').'</a>';
$html .= '
</fieldset>';
$html .= '
</form>';
return $html;
}
function build()
{
?>
<div id="admin" style="margin: 1.5em;">
<?php echo $this->prepareAdmin(); ?>
</div>
<?php
}
}

29
app/widgets/Blog/Blog.php

@ -0,0 +1,29 @@
<?php
class Blog extends WidgetCommon {
function WidgetLoad()
{
}
function build()
{
$from = $_GET['f'];
$pd = new \modl\PostnDAO();
$messages = $pd->getPublic($from);
echo '
<div class="posthead" style="border-top: 0px;">
<a
class="button tiny icon feed merged left"
href="'.Route::urlize('feed',$from).'"
target="_blank"
>
'.t('Feed').' (Atom)
</a>
</div>';
echo $this->preparePosts($messages, true);
}
}

280
app/widgets/Bookmark/Bookmark.php

@ -0,0 +1,280 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Bookmark extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('bookmark.css');
$this->registerEvent('bookmark', 'onBookmark');
$this->registerEvent('bookmarkerror', 'onBookmarkError');
$this->registerEvent('groupsubscribed', 'onGroupSubscribed');
$this->registerEvent('groupunsubscribed', 'onGroupUnsubscribed');
}
function onGroupSubscribed()
{
$arr = Cache::c('bookmark');
$html = $this->prepareBookmark($arr);
RPC::call('movim_fill', 'bookmarks', $html);
RPC::call('setBookmark');
}
function onGroupUnsubscribed()
{
$arr = Cache::c('bookmark');
$html = $this->prepareBookmark($arr);
RPC::call('movim_fill', 'bookmarks', $html);
RPC::call('setBookmark');
}
function onBookmark($arr)
{
$i = 0;
foreach($arr as $b) {
if($b['type'] == 'subscription') {
$su = new \modl\Subscription();
$su->jid = $this->user->getLogin();
$su->server = $b['server'];
$su->node = $b['node'];
$su->subscription = 'subscribed';
$su->subid = $b['subid'];
$su->timestamp = date('Y-m-d H:i:s', rand(1111111111, 8888888888));
$sd = new \modl\SubscriptionDAO();
$sd->set($su);
unset($arr[$i]);
}
$i++;
}
Cache::c('bookmark', $arr);
$html = $this->prepareBookmark($arr);
RPC::call('movim_fill', 'bookmarks', $html);
Notification::appendNotification(t('Bookmarks updated'), 'info');
}
function onBookmarkError($error)
{
Notification::appendNotification(t('An error occured : ').$error, 'error');
}
function ajaxGetBookmark()
{
$b = new moxl\BookmarkGet();
$b->request();
}
function ajaxSetBookmark($arr = null)
{
if($arr == null || $arr == '')
$arr = Cache::c('bookmark');
if($arr == null)
$arr = array();
$sd = new \modl\SubscriptionDAO();
if($sd != null) {
foreach($sd->getSubscribed() as $s) {
array_push($arr,
array(
'type' => 'subscription',
'server' => $s->server,
'title' => $s->title,
'subid' => $s->subid,
'node' => $s->node));
}
}
$b = new moxl\BookmarkSet();
$b->setArr($arr)
->request();
}
function ajaxBookmarkAdd($form)
{
if(!filter_var($form['url'], FILTER_VALIDATE_URL)) {
$html = '<div class="message error">'.t('Bad URL').'</div>' ;
RPC::call('movim_fill', 'bookmarkadderror', $html);
RPC::commit();
} elseif(trim($form['name']) == '') {
$html = '<div class="message error">'.t('Empty name').'</div>' ;
RPC::call('movim_fill', 'bookmarkadderror', $html);
RPC::commit();
} else {
$bookmarks = Cache::c('bookmark');
if($bookmarks == null)
$bookmarks = array();
array_push($bookmarks,
array(
'type' => 'url',
'name' => $form['name'],
'url' => $form['url']));
$this->ajaxSetBookmark($bookmarks);
}
}
function ajaxBookmarkUrlRemove($url)
{
$arr = Cache::c('bookmark');
foreach($arr as $key => $b) {
if($b['type'] == 'url' && $b['url'] == $url)
unset($arr[$key]);
}
$b = new moxl\BookmarkSet();
$b->setArr($arr)
->request();
}
function prepareBookmark($bookmarks)
{
$html = '';
$url = '';
$conference = '';
$subscription = '';
$sd = new \modl\SubscriptionDAO();
if($sd != null) {
foreach($sd->getSubscribed() as $s) {
$subscription .= '
<li>
<a href="'.Route::urlize('node', array($s->server, $s->node)).'">'.
$s->node.' ('.$s->server.')
</a>
</li>';
}
}
if($bookmarks == null)
$bookmarks = array();
foreach($bookmarks as $b) {
switch ($b['type']) {
case 'conference':
$conference .= '
<li>'.$b['name'].'</li>';
break;
case 'url':
$remove = $this->genCallAjax('ajaxBookmarkUrlRemove', "'".$b['url']."'");
$url .= '
<li>
<a target="_blank" href="'.$b['url'].'">'.
$b['name'].'
</a>
<a href="#" onclick="'.$remove.'">X</a>
</li>';
break;
}
}
if($subscription != '') {
$html .= '
<h3>'.t('Groups').'</h3>
<ul>'.
$subscription.'
</ul>';
}
if($url != '') {
$html .= '
<h3>'.t('Links').'</h3>
<ul>'.
$url.'
</ul>';
}
if($conference != '') {
$html .= '
<h3>'.t('Conferences').'</h3>
<ul>'.
$conference.'
</ul>';
}
$submit = $this->genCallAjax('ajaxBookmarkAdd', "movim_parse_form('bookmarkadd')");
$html .= '
<div class="popup" id="bookmarkadd">
<form name="bookmarkadd">
<fieldset>
<legend>'.t('Add a new URL').'</legend>
<div id="bookmarkadderror"></div>
<div class="element large mini">
<input name="url" placeholder="'.t('URL').'"/>
</div>
<div class="element large mini">
<input name="name" placeholder="'.t('Name').'"/>
</div>
</fieldset>
<a
class="button icon yes black merged left"
onclick="'.$submit.'"
>'.
t('Add').'
</a><a
class="button icon black merged right"
onclick="movim_toggle_display(\'#bookmarkadd\')"
>'.
t('Close').'
</a>
</form>
</div>
';
return $html;
}
function build()
{
$getbookmark = $this->genCallAjax("ajaxGetBookmark");
$setbookmark = $this->genCallAjax("ajaxSetBookmark", "''");
?>
<script type="text/javascript">
function setBookmark() {
<?php echo $setbookmark; ?>
}
</script>
<?php
?>
<h2><?php echo t('Bookmarks'); ?></h2>
<div id="bookmarks">
<?php echo $this->prepareBookmark(Cache::c('bookmark')); ?>
</div>
<br />
<a class="button color blue icon add merged right" style="float: right;"
onclick="movim_toggle_display('#bookmarkadd')"><?php echo('Add'); ?></a>
<a class="button black icon refresh merged left" style="float: right;"
onclick="<?php echo $getbookmark; ?>"><?php echo('Refresh'); ?></a>
<br />
<?php
}
}

7
app/widgets/Bookmark/bookmark.css

@ -0,0 +1,7 @@
#bookmarks li {
white-space: nowrap;
width: auto;
overflow: hidden;
text-overflow: ellipsis;
line-height: 2em;
}

437
app/widgets/Chat/Chat.php

@ -0,0 +1,437 @@
<?php
/**
* @package Widgets
*
* @file Chat.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Chat extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('chat.css');
$this->addjs('chat.js');
$this->registerEvent('message', 'onMessage');
$this->registerEvent('messagepublished', 'onMessagePublished');
$this->registerEvent('composing', 'onComposing');
$this->registerEvent('paused', 'onPaused');
$this->registerEvent('attention', 'onAttention');
$this->registerEvent('presence', 'onPresence');
}
function onPresence($presence)
{
$arr = $presence->getPresence();
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
if(isset($contact) && $contact->chaton == 1) {
$txt = array(
1 => t('Online'),
2 => t('Away'),
3 => t('Do Not Disturb'),
4 => t('Extended Away'),
5 => t('Offline'),
);
$html = '
<div class="message presence">
<span class="date">'.date('G:i', time()).'</span>'.
prepareString(htmlentities($txt[$arr['presence']], ENT_COMPAT, "UTF-8")).'
</div>';
RPC::call('movim_append',
'messages'.$arr['jid'],
$html);
RPC::call('scrollTalk',
'messages'.$arr['jid']);
}
}
function onMessage($message)
{
if($message->key == $message->from) {
$key = $message->from;
$jid = $message->to;
} else {
$key = $message->to;
$jid = $message->from;
}
if($message->key != $message->from)
RPC::call('notify');
$rd = new \modl\RosterLinkDAO();
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
if(isset($contact) && $contact->chaton == 0) {
$contact->chaton = 2;
$rd->setChat($jid, 2);
$evt = new Event();
$evt->runEvent('openchat');
RPC::call('movim_prepend',
'chats',
$this->prepareChat($contact));
RPC::call('scrollAllTalks');
} else if(isset($contact) && $message->body != '') {
$html = $this->prepareMessage($message);
if($contact->chaton == 1) {
RPC::call('colorTalk',
'messages'.$contact->jid);
}
RPC::call('movim_append',
'messages'.$contact->jid,
$html);
RPC::call('hideComposing',
$contact->jid);
RPC::call('hidePaused',
$contact->jid);
RPC::call('scrollTalk',
'messages'.$contact->jid);
}
}
function onMessagePublished($jid)
{
Notification::appendNotification(t('Message Published'), 'success');
}
function onComposing($jid)
{
$rd = new \modl\RosterLinkDAO();
$contact = $rd->get(echapJid($jid));
if(in_array($contact->chaton, array(1, 2))) {
RPC::call('showComposing',
$contact->jid);
RPC::call('scrollTalk',
'messages'.$contact->jid);
}
}
function onPaused($jid)
{
$rd = new \modl\RosterLinkDAO();
$contact = $rd->get(echapJid($jid));
if(in_array($contact->chaton, array(1, 2))) {
RPC::call('showPaused',
$contact->jid);
RPC::call('scrollTalk',
'messages'.$contact->jid);
}
}
function onAttention($jid)
{
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
$html = '
<div style="font-weight: bold; color: black;" class="message" >
<span class="date">'.date('G:i', time()).'</span>'.
t('%s needs your attention', $contact->getTrueName()).'
</div>';
RPC::call('movim_append',
'messages'.$jid,
$html);
RPC::call('scrollTalk',
'messages'.$jid);
}
/**
* Open a new talk
*
* @param string $jid
* @return void
*/
function ajaxOpenTalk($jid)
{
$rc = new \modl\ContactDAO();
$contact = $rc->getRosterItem(echapJid($jid));
if(
isset($contact)
&& $contact->chaton == 0
&& !in_array($contact->presence, array(5, 6))) {
$contact->chaton = 2;
$rd = new \modl\RosterLinkDAO();
$rd->setChat($jid, 2);
RPC::call('movim_prepend',
'chats',
$this->prepareChat($contact));
RPC::call('scrollAllTalks');
RPC::commit();
}
$evt = new Event();
$evt->runEvent('openchat');
}
/**
* Send a message
*
* @param string $to
* @param string $message
* @return void
*/
function ajaxSendMessage($to, $message)
{
$m = new \modl\Message();
$m->key = $this->user->getLogin();
$m->to = echapJid($to);
$m->from = $this->user->getLogin();
$m->type = 'chat';
$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);
$evt = new Event();
$evt->runEvent('message', $m);
// We decode URL codes to send the correct message to the XMPP server
$m = new \moxl\MessagePublish();
$m->setTo($to)
->setContent(htmlspecialchars(rawurldecode($message)))
->request();
}
/**
* Send a "composing" message
*
* @param string $to
* @return void
*/
function ajaxSendComposing($to)
{
$mc = new \moxl\MessageComposing();
$mc->setTo($to)
->request();
}
/**
* Send a "paused" message
*
* @param string $to
* @return void
*/
function ajaxSendPaused($to)
{
$mp = new \moxl\MessagePaused();
$mp->setTo($to)
->request();
}
/**
* Close a talk
*
* @param string $jid
* @return void
*/
function ajaxCloseTalk($jid)
{
$rd = new \modl\RosterLinkDAO();
$contacts = $rd->getChats();
foreach($contacts as $contact) {
if(
$contact->jid == $jid
&& (
(int)$contact->chaton == 1
|| (int)$contact->chaton == 2)
) {
$contact->chaton = 0;
$rd->setNow($contact);
}
}
RPC::call('movim_delete',
'chat'.$jid);
$evt = new Event();
$evt->runEvent('closechat');
}
function ajaxHideTalk($jid)
{
$rd = new \modl\RosterLinkDAO();
$contact = $rd->get(echapJid($jid));
if($contact->chaton == 1)
$contact->chaton = 2;
else
$contact->chaton = 1;
$rd->setNow($contact);
RPC::call('scrollTalk',
'messages'.$contact->jid);
RPC::commit();
}
function prepareMessage($message) {
if($message->body != '') {
$html = '<div class="message ';
if($message->key == $message->from)
$html.= 'me';
$content = $message->body;
if(preg_match("#^/me#", $message->body)) {
$html .= " own ";
$content = "** ".substr($message->body, 4);
}
$html .= '"><span class="date">'.date('H:i', strtotime($message->published)).'</span>';
$html.= prepareString(htmlentities($content, ENT_COMPAT, "UTF-8")).'</div>';
return $html;
} else {
return '';
}
}
function prepareChats()
{
$rc = new \modl\ContactDAO();
$contacts = $rc->getRosterChat();
if(isset($contacts)) {
foreach($contacts as $contact) {
$html .= trim($this->prepareChat($contact));
}
}
return $html;
}
function prepareChat($contact)
{
$md = new \modl\MessageDAO();
$messages = $md->getContact($contact->jid, 0, 10);
if(!empty($messages)) {
$day = '';
foreach($messages as $m) {
if($day != date('d',strtotime($m->published))) {
$messageshtml .= '<div class="message presence">'.prepareDate(strtotime($m->published), false).'</div>';
$day = date('d',strtotime($m->published));
}
$messageshtml .= $this->prepareMessage($m);
}
}
$style = '';
if($contact->chaton == 2) {
$tabstyle = ' style="display: none;" ';
$panelstyle = ' style="display: block;" ';
}
$html = '
<div class="chat"
onclick="this.querySelector(\'textarea\').focus()"
id="chat'.$contact->jid.'">
<div class="panel" '.$panelstyle.'>
<div class="head" >
<span class="chatbutton cross" onclick="'.$this->genCallAjax("ajaxCloseTalk", "'".$contact->jid."'").'"></span>
<span class="chatbutton arrow" onclick="'.$this->genCallAjax("ajaxHideTalk", "'".$contact->jid."'").' hideTalk(this)"></span>
<img class="avatar" src="'.$contact->getPhoto('xs').'" />
<a class="name" href="'.Route::urlize('friend',$contact->jid).'">
'.$contact->getTrueName().'
</a>
</div>
<div class="messages" id="messages'.$contact->jid.'">
'.$messageshtml.'
<div style="display: none;" class="message" id="composing'.$contact->jid.'">'.t('Composing...').'</div>
<div style="display: none;" class="message" id="paused'.$contact->jid.'">'.t('Paused...').'</div>
</div>
<div class="text">
<textarea
rows="1"
id="textarea'.$contact->jid.'"
onkeypress="
if(event.keyCode == 13) {
'.$this->genCallAjax('ajaxSendMessage', "'".$contact->jid."'", "sendMessage(this, '".$contact->jid."')").'
lastkeypress = new Date().getTime()+1000;
return false;
}
if(lastkeypress < new Date().getTime())
'.$this->genCallAjax('ajaxSendComposing', "'".$contact->jid."'").'
lastkeypress = new Date().getTime()+1000;
"
onkeyup="
movim_textarea_autoheight(this);
var val = this.value;
setTimeout(function()
{
if(lastkeypress < new Date().getTime() && val != \'\') {
'.$this->genCallAjax('ajaxSendPaused', "'".$contact->jid."'").'
lastkeypress = new Date().getTime()+1000;
}
},1100); // Listen for 2 seconds of silence
"
></textarea>
</div>
</div>
<div class="tab '.$tabclass.'" '.$tabstyle.' onclick="'.$this->genCallAjax("ajaxHideTalk", "'".$contact->jid."'").' showTalk(this);">
<div class="name">
<img class="avatar" src="'.$contact->getPhoto('xs').'" />'.$contact->getTrueName().'
</div>
</div>
</div>
';
return $html;
}
function build()
{
echo '<div id="chats">';
echo $this->prepareChats();
echo '</div>';
}
}

181
app/widgets/Chat/chat.css

@ -0,0 +1,181 @@
#chats {
position: fixed;
bottom: -4px;
right: 210px;
z-index: 3;
}
#chats .chat {
display: inline-block;
position: relative;
bottom: 0;
overflow: hidden;
margin-left: 0.5em;
}
#chats .chat .panel {
display: none;
}
#chats .chat .tab {
background-color: #272727;
color: white;
}
#chats .chat .tab.alert .name {
display: relative;
}
#chats .chat .tab.alert .name:after {
content: "+1";
color: white;
font-size: 10px;
padding: 0px;
line-height: 1.7em;
float: right;
background-color: #C5371E;
margin-top: 3px;
padding: 0px 8px;
margin-left: 10px;
}
#chats .chat .tab:hover {
background-color: #333;
}
#chats .chat .tab .name {
line-height: 2em;
padding-right: 0.5em;
}
#chats .chat .tab .name img {
float: left;
margin-right: 0.5em;
}
#chats .chat .tab:hover {
cursor: pointer;
}
#chats .chat .panel {
background-color: white;
width: 225px;
}
#chats .chat .panel .head {
background-color: #272727;
height: 2em;
}
#chats .chat .panel .head span.chatbutton {
width: 0px;
height: 0px;
display: block;
background-position: center center;
background-repeat: no-repeat;
padding: 1em;
float: right;
}
#chats .chat .panel .head span.chatbutton:hover {
background-color: #333;
}
#chats .chat .panel .head span.chatbutton.cross {
background-image: url(img/cross.png);
}
#chats .chat .panel .head span.chatbutton.arrow {
background-image: url(img/arrow.png);
}
#chats .chat .panel .head a.name {
padding-right: 0.5em;
line-height: 2em;
display: inline-block;
margin: 0px;
width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#chats .chat .panel .head:hover {
cursor: pointer;
}
#chats .chat .panel .head > * {
color: white;
}
#chats .chat .panel .head a:hover {
text-decoration: underline;
}
#chats .chat .panel .head img {
margin-right: 0.5em;
float: left;
}
#chats .chat .panel .messages {
background-color: white;
color: gray;
max-height: 250px;
overflow: auto;
min-height: 3em;
border: 1px solid #888;
border-top: 0px;
border-bottom: 0px;
}
#chats .chat .panel .text {
overflow: hidden;
border: 1px solid #888;
}
#chats .chat .panel .text textarea {
width: 100%;
border: 0px;
padding: 0.2em;
overflow: auto;
background-color: white;
resize: none;
font-size: 1em;
height: 1.3em;
overflow-y: hidden;
}
#chats .chat .panel .text textarea:focus {
border: 0px;
}
#chats .chat .panel .messages .message {
padding: 5px;
word-wrap: break-word;
font-size: 12px;
}
#chats .chat .panel .messages .message.me {
background-color: #FFC;
}
#chats .chat .panel .messages .message.own {
color: blue;
}
#chats .chat .panel .messages .message.presence {
color: black;
font-weight: bold;
}
#chats .chat .panel .messages .message span.date {
float: right;
color: #ccc;
padding: 2px;
line-height: 1em;
}
#chats .chat .panel .messages .message.me span.date {
color: #444;
}

102
app/widgets/Chat/chat.js

@ -0,0 +1,102 @@
function scrollAllTalks() {
var mes = document.querySelectorAll('.messages');
for (var i=0; i<mes.length; i++){
// We add 200px to prevent smiley loading
mes.item(i).scrollTop = mes.item(i).scrollHeight + 200;
}
}
//Loads the Notification sound.
var chatSoundNotif = document.createElement('audio');
chatSoundNotif.setAttribute('src', './system/Widget/widgets/Chat/sound/notif.ogg');
chatSoundNotif.load();
chatSoundNotif.volume = 1;
movim_add_onload(function()
{
scrollAllTalks();
});
function colorTalk(params) {
messages = document.getElementById(params);
tabstyle = messages.parentNode.parentNode.querySelector('.tab').className = 'tab alert';
}
function showTalk(n) {
panel = n.parentNode.querySelector('.panel');
panel.style.display = 'block';
n.style.display = 'none';
n.className = 'tab';
}
function hideTalk(n) {
panel = n.parentNode.parentNode.parentNode.querySelector('.panel');
tab = n.parentNode.parentNode.parentNode.querySelector('.tab');
panel.style.display = 'none';
tab.style.display = 'block';
}
function scrollTalk(params) {
var messages = document.getElementById(params);
messages.scrollTop = messages.scrollHeight;
}
function showComposing(jid) {
var box = document.getElementById('messages' + jid);
var composing = document.getElementById('composing' + jid);
hidePaused(jid);
box.appendChild(composing);
composing.style.display = 'block';
}
function showPaused(jid) {
var box = document.getElementById('messages' + jid);
var paused = document.getElementById('paused' + jid);
hideComposing(jid);
box.appendChild(paused);
paused.style.display = 'block';
}
function notify() {
if(document_focus == false) {
movim_title_inc();
//play the notif sound
chatSoundNotif.pause();
chatSoundNotif.currentTime= 0;
chatSoundNotif.play();
}
}
function hideComposing(jid) {
var composing = document.getElementById('composing' + jid);
composing.style.display = 'none';
}
function hidePaused(jid) {
var paused = document.getElementById('paused' + jid);
paused.style.display = 'none';
}
function sendMessage(n, jid)
{
var text = n.value;
n.value = "";
n.focus();
// We escape the text to prevent XML errors
return encodeURIComponent(text);
}
function disableSound(){
chatSoundNotif.volume = 0;
}

BIN
app/widgets/Chat/img/arrow.png

After

Width: 11  |  Height: 11  |  Size: 263 B

BIN
app/widgets/Chat/img/cross.png

After

Width: 11  |  Height: 11  |  Size: 376 B

BIN
app/widgets/Chat/sound/notif.ogg

150
app/widgets/ChatExt/ChatExt.php

@ -0,0 +1,150 @@
<?php
/**
* @package Widgets
*
* @file ChatExt.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
require_once(APP_PATH . "widgets/Chat/Chat.php");
class ChatExt extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('chatext.css');
$this->addjs('chatext.js');
$this->registerEvent('message', 'onMessage');
$this->registerEvent('openchat', 'onEvent');
$this->registerEvent('closechat', 'onEvent');
}
function prepareChat($contact)
{
$md = new \modl\MessageDAO();
$messages = $md->getContact($contact->jid, 0, 10);
if(!empty($messages)) {
$day = '';
foreach($messages as $m) {
if($day != date('d',strtotime($m->published))) {
$messageshtml .= '<div class="message presence">'.prepareDate(strtotime($m->published), false).'</div>';
$day = date('d',strtotime($m->published));
}
$chat = new Chat();
$messageshtml .= $chat->prepareMessage($m);
}
}
$style = '';
if($contact->chaton == 2) {
$tabstyle = ' style="display: none;" ';
$panelstyle = ' style="display: block;" ';
}
$html = '
<div class="chat" onclick="this.querySelector(\'textarea\').focus()">
<div class="messages" id="messages'.$contact->jid.'">
'.$messageshtml.'
<div style="display: none;" class="message" id="composing'.$contact->jid.'">'.t('Composing...').'</div>
<div style="display: none;" class="message" id="paused'.$contact->jid.'">'.t('Paused...').'</div>
</div>
<div class="text">
<textarea
rows="1"
onkeyup="movim_textarea_autoheight(this);"
onkeypress="if(event.keyCode == 13) { self.opener.'.$this->genCallWidget('Chat','ajaxSendMessage', "'".$contact->jid."'", "sendMessage(this, '".$contact->jid."')").' return false; }"
></textarea>
</div>
</div>
';
return $html;
}
function prepareList($contact, $first = false)
{
if($first)
$checked = ' checked ';
$html .= '
<li>
<input type="radio" name="contact" id="contact'.$contact->jid.'" '.$checked.'/>
<label class="tab" for="contact'.$contact->jid.'" onclick="setTimeout(function() {scrollAllTalks()}, 100);">
<img class="avatar" src="'.$contact->getPhoto('xs').'" />'.
$contact->getTrueName().'
</label>
<div class="content">'.trim($this->prepareChat($contact)).'
<span
class="chatbutton cross"
onclick="self.opener.'.$this->genCallWidget('Chat','ajaxCloseTalk', "'".$contact->jid."'").'"></span>
</div>
</li>';
return $html;
}
function onEvent()
{
if(!Cache::c('chatpop')) {
$html = $this->preparePop();
RPC::call('popUpEvent', 'movim_fill', 'chatpop', $html);
RPC::call('popUpEvent', 'scrollAllTalks');
}
}
function preparePop()
{
$rc = new \modl\ContactDAO();
$contacts = $rc->getRosterChat();
$list = '';
if(isset($contacts)) {
$first = true;
foreach($contacts as $contact) {
$list .= $this->prepareList($contact, $first);
$first = false;
}
$html = '<ul id="chatpoplist">'.$list.'</ul>';
}
return $html;
}
function onMessage($message)
{
if($message->key == $message->from) {
$key = $message->from;
$jid = $message->to;
} else {
$key = $message->to;
$jid = $message->from;
}
$chatpop = Cache::c('chatpop');
if(!$chatpop) {
$chat = new Chat();
RPC::call('popUpEvent', 'movim_append', 'messages'.$jid, $chat->prepareMessage($message));
RPC::call('popUpEvent', 'scrollAllTalks');
}
}
function build()
{
}
}

0
app/widgets/ChatExt/chatext.css

31
app/widgets/ChatExt/chatext.js

@ -0,0 +1,31 @@
// Initialise popup pointer
var popupWin = null;
function openPopup() {
var url = "?q=chatpop"
if( !popupWin || popupWin.closed ) {
popupWin = window.open( url, "popupWin", "height=400,width=600,directories=0,titlebar=0,toolbar=0,location=0,status=0,menubar=0,resizable=no" );
} else popupWin.focus();
}
function closePopup() {
popupWin.close();
}
function focusPopup() {
popupWin.focus();
}
function popUpEvent(args) {
if( popupWin && !popupWin.closed ) {
// The popup is open so call it
var func = args[0];
args.shift();
var params = args;
window['popupWin'][func](params);
} else {
// The popup is closed so open it
openPopup();
}
}

45
app/widgets/ChatPop/ChatPop.php

@ -0,0 +1,45 @@
<?php
/**
* @package Widgets
*
* @file ChatExt.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
require_once(APP_PATH . "widgets/ChatExt/ChatExt.php");
class ChatPop extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('chatpop.css');
$this->addjs('chatpop.js');
}
function build()
{
$chatext = new ChatExt();
echo '<div id="chatpop">';
echo $chatext->preparePop();
echo '</div>';
?>
<div id="connection">
<?php echo t('Connection').'...'; ?>
</div>
<?php
}
}

161
app/widgets/ChatPop/chatpop.css

@ -0,0 +1,161 @@
body {
margin: 0px;
background-color: #333;
font-family: sans-serif;
}
#connection {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.6);
display: none;
color: white;
font-size: 1.5em;
text-align: center;
line-height: 5em;
}
#chatpop {
height: 100%;
width: 100%;
position: fixed;
top: 0px;
left: 0px;
}
#chatpop #chatpoplist label {
display: block;
}
#chatpop #chatpoplist li input[type=radio] {
display: none;
}
#chatpop #chatpoplist li input[type=radio]:checked ~ .content {
display: block;
}
#chatpop #chatpoplist input[type=radio]:checked ~ label {
background-color: #111;
}
#chatpop #chatpoplist {
width: 25%;
height: 100%;
list-style-type: none;
margin: 0px;
overflow-y: auto;
display: block;
padding: 0px;
}
#chatpop #chatpoplist li {
margin: 0px;
padding: 0px;
}
#chatpop #chatpoplist li .tab {
white-space: nowrap;
width: auto;
overflow: hidden;
color: #BBB;
line-height: 30px;
font-size: 13px;
text-overflow: ellipsis;
}
#chatpop #chatpoplist li:hover .tab {
background-color: #222;
cursor: pointer;
}
#chatpop #chatpoplist li .tab img.avatar {
float: left;
margin-right: 5px;
width: 30px;
}
#chatpop #chatpoplist li .content {
position: fixed;
top: 0px;
right: 0px;
height: 90%;
width: 75%;
display: none;
background-color: white;
overflow-y: auto;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
}
#chatpop #chatpoplist li .content .text {
position: fixed;
bottom: 0px;
right: 0px;
width: 75%;
background-color: red;
min-height: 10%;
border-top: 1px solid #333;
background-color: white;
}
#chatpop #chatpoplist li .content .text textarea {
width: 100%;
margin: 0px;
padding: 0px;
border: 0px;
height: auto;
background-color: white;
resize: none;
}
#chatpop #chatpoplist li .content .messages {
font-size: 13px;
}
#chatpop #chatpoplist li .content .messages .message {
margin: 10px;
margin-right: 30px;
background-color: #FFE8CC;
padding: 5px;
min-height: 25px;
}
#chatpop #chatpoplist li .content .messages .message.me {
margin-left: 30px;
margin-right: 10px;
background-color: #FFFFCC;
}
#chatpop #chatpoplist li .content .messages .message .date {
float: right;
color: #888;
font-size: 11px;
padding-left: 10px;
}
#chatpop #chatpoplist li .content .messages .message.presence {
background-color: transparent;
font-weight: bold;
min-height: 0px;
}
#chatpop #chatpoplist span.chatbutton {
width: 28px;
height: 28px;
background-repeat: no-repeat;
background-position: center center;
position: fixed;
bottom: 0px;
left: 0px;
}
#chatpop #chatpoplist span.chatbutton:hover {
cursor: pointer;
}
#chatpop #chatpoplist li span.chatbutton.cross {
background-image: url(img/cross.png);
}

46
app/widgets/ChatPop/chatpop.js

@ -0,0 +1,46 @@
function notifyOpener() {
document.querySelector('#connection').style.display = 'none';
if(self.opener || !self.opener.popupWin)
self.opener.popupWin = self;
}
setInterval( notifyOpener, 200 );
self.focus();
function doSomething() {
alert("I'm doing something");
}
function handleError() {
document.querySelector('#connection').style.display = 'block';
}
window.onerror = handleError;
window.onunload = function() {
self.opener.Roster_ajaxToggleChat();
};
function scrollAllTalks() {
var mes = document.querySelectorAll('.content');
for (var i=0; i<mes.length; i++){
// We add 200px to prevent smiley loading
mes.item(i).scrollTop = mes.item(i).scrollHeight + 200;
}
}
function sendMessage(n, jid)
{
var text = n.value;
n.value = "";
n.focus();
// We escape the text to prevent XML errors
return encodeURIComponent(text);
}
//setInterval( scrollAllTalks, 200 );

BIN
app/widgets/ChatPop/img/cross.png

After

Width: 11  |  Height: 11  |  Size: 376 B

196
app/widgets/Config/Config.php

@ -0,0 +1,196 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Config extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('config.css');
$this->addjs('color/jscolor.js');
$this->registerEvent('config', 'onConfig');
}
function onConfig(array $data)
{
$this->user->setConfig($data);
Notification::appendNotification(t('Configuration updated'));
}
function ajaxSubmit($data) {
$config = $this->user->getConfig();
if(isset($config))
$data = array_merge($config, $data);
$s = new moxl\StorageSet();
$s->setXmlns('movim:prefs')
->setData(serialize($data))
->request();
}
function ajaxGet() {
$s = new moxl\StorageGet();
$s->setXmlns('movim:prefs')
->request();
}
function build()
{
$languages = load_lang_array();
/* We load the user configuration */
$conf = $this->user->getConfig('language');
$color = $this->user->getConfig('color');
$submit = $this->genCallAjax('ajaxSubmit', "movim_parse_form('general')")
. "this.className='button icon color orange loading'; setTimeout(function() {location.reload(false)}, 2000); this.onclick=null;";
?>
<div class="tabelem padded" title="<?php echo t('Configuration'); ?>" id="config" >
<form enctype="multipart/form-data" method="post" action="index.php" name="general">
<fieldset>
<legend><?php echo t('General'); ?></legend>
<div class="element">
<label for="language"><?php echo t('Language'); ?></label>
<div class="select">
<select name="language" id="language">
<option value="en">English (default)</option>
<?php
foreach($languages as $key => $value ) {
if($key == $conf) { ?>
<option value="<?php echo $key; ?>" selected="selected"><?php echo $value; ?></option>
<?php } else {?>
<option value="<?php echo $key; ?>"><?php echo $value; ?></option>
<?php }
} ?>
</select>
</div>
</div>
</fieldset>
<fieldset>
<legend><?php echo t('Apparence'); ?></legend>
<div class="element">
<label for="color"><?php echo t('Background color'); ?></label>
<a
type="button"
onclick="
document.querySelector('input[name=color]').value = '082D50';
document.body.style.backgroundColor = '#082D50';"
style="width: 45%; float: right;"
class="button icon color purple back">
<?php echo t('Reset');?>
</a>
<input
style="box-shadow: none; width: 50%; float: left;"
name="color"
class="color"
onchange="document.body.style.backgroundColor = '#'+this.value;"
value="
<?php
if(isset($color))
echo $color;
else
echo "082D50";
?>
">
</div>
<div class="element large">
<label for="pattern"><?php echo t('Pattern'); ?></label>
<input type="radio" name="pattern" id="argyle" value="argyle"/>
<label for="argyle"><span></span>
<div class="preview argyle"
style="background-color: #6d695c;"></div>
</label>
<input type="radio" name="pattern" id="default" value="default"/>
<label for="default"><span></span>
<div class="preview default"
style="background-color: #082D50;;"></div>
</label>
<input type="radio" name="pattern" id="tableclothe" value="tableclothe"/>
<label for="tableclothe"><span></span>
<div class="preview tableclothe"
style="background-color: rgba(200, 0, 0, 1);"></div>
</label>
<input type="radio" name="pattern" id="blueprint" value="blueprint"/>
<label for="blueprint"><span></span>
<div class="preview blueprint"
style="background-color:#269;"></div>
</label>
<input type="radio" name="pattern" id="cicada" value="cicada"/>
<label for="cicada"><span></span>
<div class="preview cicada"
style="background-color: #026873;"></div>
</label>
<input type="radio" name="pattern" id="stripes" value="stripes"/>
<label for="stripes"><span></span>
<div class="preview stripes"
style="background-color: orange;"></div>
</label>
<input type="radio" name="pattern" id="stars" value="stars"/>
<label for="stars"><span></span>
<div class="preview stars"
style="background-color:black; background-size: 100px 100px;"></div>
</label>
<input type="radio" name="pattern" id="paper" value="paper"/>
<label for="paper"><span></span>
<div class="preview paper"
style="background-color: #23343E;"></div>
</label>
<input type="radio" name="pattern" id="tartan" value="tartan"/>
<label for="tartan"><span></span>
<div class="preview tartan"
style="background-color: hsl(2, 57%, 40%);"></div>
</label>
<input type="radio" name="pattern" id="empty" value=""/>
<label for="empty"><span></span>
<div class="preview empty"
style="background-color: white;"></div>
</label>
</div>
</fieldset>
<br />
<hr />
<!--<label id="lock" for="soundnotif"><?php echo t('Enable Sound Notification:'); ?></label>
<input type="checkbox" name="soundnotif" value="soundnotif" checked="checked" /><br /> -->
<!--<input value="<?php echo t('Submit'); ?>" onclick="<?php echo $submit; ?>" type="button" class="button icon yes merged right" style="float: right;">
<input type="reset" value="<?php echo t('Reset'); ?>" class="button icon no merged left" style="float: right;">-->
<br />
<a onclick="<?php echo $submit; ?>" type="button" class="button icon yes color green" style="float: right;"><?php echo t('Submit'); ?></a>
<!--<a type="reset" value="<?php echo t('Reset'); ?>" class="button icon no merged left" style="float: right;">-->
</p>
</form>
<br /><br />
<div class="message info"><?php echo t("This configuration is shared wherever you are connected !");?></div>
</div>
<?php
}
}

BIN
app/widgets/Config/color/arrow.gif

After

Width: 7  |  Height: 11  |  Size: 66 B

BIN
app/widgets/Config/color/cross.gif

After

Width: 15  |  Height: 15  |  Size: 83 B

12
app/widgets/Config/color/demo.html

@ -0,0 +1,12 @@
<html>
<head>
<title>jscolor demo</title>
</head>
<body>
<script type="text/javascript" src="jscolor.js"></script>
Click here: <input class="color" value="66ff00">
</body>
</html>

BIN
app/widgets/Config/color/hs.png

After

Width: 181  |  Height: 101  |  Size: 2.6 KiB

BIN
app/widgets/Config/color/hv.png

After

Width: 181  |  Height: 101  |  Size: 2.8 KiB

953
app/widgets/Config/color/jscolor.js

@ -0,0 +1,953 @@
/**
* jscolor, JavaScript Color Picker
*
* @version 1.4.0
* @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
* @author Jan Odvarko, http://odvarko.cz
* @created 2008-06-15
* @updated 2012-07-06
* @link http://jscolor.com
*/
var jscolor = {
dir : '', // location of jscolor directory (leave empty to autodetect)
bindClass : 'color', // class name
binding : true, // automatic binding via <input class="...">
preloading : true, // use image preloading?
install : function() {
jscolor.addEvent(window, 'load', jscolor.init);
},
init : function() {
if(jscolor.binding) {
jscolor.bind();
}
if(jscolor.preloading) {
jscolor.preload();
}
},
getDir : function() {
if(!jscolor.dir) {
var detected = jscolor.detectDir();
jscolor.dir = detected!==false ? detected : 'jscolor/';
}
return jscolor.dir;
},
detectDir : function() {
var base = location.href;
var e = document.getElementsByTagName('base');
for(var i=0; i<e.length; i+=1) {
if(e[i].href) { base = e[i].href; }
}
var e = document.getElementsByTagName('script');
for(var i=0; i<e.length; i+=1) {
if(e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
var src = new jscolor.URI(e[i].src);
var srcAbs = src.toAbsolute(base);
srcAbs.path = srcAbs.path.replace(/[^\/]+$/, ''); // remove filename
srcAbs.query = null;
srcAbs.fragment = null;
return srcAbs.toString();
}
}
return false;
},
bind : function() {
var matchClass = new RegExp('(^|\\s)('+jscolor.bindClass+')\\s*(\\{[^}]*\\})?', 'i');
var e = document.getElementsByTagName('input');
for(var i=0; i<e.length; i+=1) {
var m;
if(!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
var prop = {};
if(m[3]) {
try {
prop = (new Function ('return (' + m[3] + ')'))();
} catch(eInvalidProp) {}
}
e[i].color = new jscolor.color(e[i], prop);
}
}
},
preload : function() {
for(var fn in jscolor.imgRequire) {
if(jscolor.imgRequire.hasOwnProperty(fn)) {
jscolor.loadImage(fn);
}
}
},
images : {
pad : [ 181, 101 ],
sld : [ 16, 101 ],
cross : [ 15, 15 ],
arrow : [ 7, 11 ]
},
imgRequire : {},
imgLoaded : {},
requireImage : function(filename) {
jscolor.imgRequire[filename] = true;
},
loadImage : function(filename) {
if(!jscolor.imgLoaded[filename]) {
jscolor.imgLoaded[filename] = new Image();
jscolor.imgLoaded[filename].src = jscolor.getDir()+filename;
}
},
fetchElement : function(mixed) {
return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
},
addEvent : function(el, evnt, func) {
if(el.addEventListener) {
el.addEventListener(evnt, func, false);
} else if(el.attachEvent) {
el.attachEvent('on'+evnt, func);
}
},
fireEvent : function(el, evnt) {
if(!el) {
return;
}
if(document.createEvent) {
var ev = document.createEvent('HTMLEvents');
ev.initEvent(evnt, true, true);
el.dispatchEvent(ev);
} else if(document.createEventObject) {
var ev = document.createEventObject();
el.fireEvent('on'+evnt, ev);
} else if(el['on'+evnt]) { // alternatively use the traditional event model (IE5)
el['on'+evnt]();
}
},
getElementPos : function(e) {
var e1=e, e2=e;
var x=0, y=0;
if(e1.offsetParent) {
do {
x += e1.offsetLeft;
y += e1.offsetTop;
} while(e1 = e1.offsetParent);
}
while((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
x -= e2.scrollLeft;
y -= e2.scrollTop;
}
return [x, y];
},
getElementSize : function(e) {
return [e.offsetWidth, e.offsetHeight];
},
getRelMousePos : function(e) {
var x = 0, y = 0;
if (!e) { e = window.event; }
if (typeof e.offsetX === 'number') {
x = e.offsetX;
y = e.offsetY;
} else if (typeof e.layerX === 'number') {
x = e.layerX;
y = e.layerY;
}
return { x: x, y: y };
},
getViewPos : function() {
if(typeof window.pageYOffset === 'number') {
return [window.pageXOffset, window.pageYOffset];
} else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
return [document.body.scrollLeft, document.body.scrollTop];
} else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
} else {
return [0, 0];
}
},
getViewSize : function() {
if(typeof window.innerWidth === 'number') {
return [window.innerWidth, window.innerHeight];
} else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
return [document.body.clientWidth, document.body.clientHeight];
} else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
return [document.documentElement.clientWidth, document.documentElement.clientHeight];
} else {
return [0, 0];
}
},
URI : function(uri) { // See RFC3986
this.scheme = null;
this.authority = null;
this.path = '';
this.query = null;
this.fragment = null;
this.parse = function(uri) {
var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
this.scheme = m[3] ? m[2] : null;
this.authority = m[5] ? m[6] : null;
this.path = m[7];
this.query = m[9] ? m[10] : null;
this.fragment = m[12] ? m[13] : null;
return this;
};
this.toString = function() {
var result = '';
if(this.scheme !== null) { result = result + this.scheme + ':'; }
if(this.authority !== null) { result = result + '//' + this.authority; }
if(this.path !== null) { result = result + this.path; }
if(this.query !== null) { result = result + '?' + this.query; }
if(this.fragment !== null) { result = result + '#' + this.fragment; }
return result;
};
this.toAbsolute = function(base) {
var base = new jscolor.URI(base);
var r = this;
var t = new jscolor.URI;
if(base.scheme === null) { return false; }
if(r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
r.scheme = null;
}
if(r.scheme !== null) {
t.scheme = r.scheme;
t.authority = r.authority;
t.path = removeDotSegments(r.path);
t.query = r.query;
} else {
if(r.authority !== null) {
t.authority = r.authority;
t.path = removeDotSegments(r.path);
t.query = r.query;
} else {
if(r.path === '') {
t.path = base.path;
if(r.query !== null) {
t.query = r.query;
} else {
t.query = base.query;
}
} else {
if(r.path.substr(0,1) === '/') {
t.path = removeDotSegments(r.path);
} else {
if(base.authority !== null && base.path === '') {
t.path = '/'+r.path;
} else {
t.path = base.path.replace(/[^\/]+$/,'')+r.path;
}
t.path = removeDotSegments(t.path);
}
t.query = r.query;
}
t.authority = base.authority;
}
t.scheme = base.scheme;
}
t.fragment = r.fragment;
return t;
};
function removeDotSegments(path) {
var out = '';
while(path) {
if(path.substr(0,3)==='../' || path.substr(0,2)==='./') {
path = path.replace(/^\.+/,'').substr(1);
} else if(path.substr(0,3)==='/./' || path==='/.') {
path = '/'+path.substr(3);
} else if(path.substr(0,4)==='/../' || path==='/..') {
path = '/'+path.substr(4);
out = out.replace(/\/?[^\/]*$/, '');
} else if(path==='.' || path==='..') {
path = '';
} else {
var rm = path.match(/^\/?[^\/]*/)[0];
path = path.substr(rm.length);
out = out + rm;
}
}
return out;
}
if(uri) {
this.parse(uri);
}
},
/*
* Usage example:
* var myColor = new jscolor.color(myInputElement)
*/
color : function(target, prop) {
this.required = true; // refuse empty values?
this.adjust = true; // adjust value to uniform notation?
this.hash = false; // prefix color with # symbol?
this.caps = true; // uppercase?
this.slider = true; // show the value/saturation slider?
this.valueElement = target; // value holder
this.styleElement = target; // where to reflect current color
this.onImmediateChange = null; // onchange callback (can be either string or function)
this.hsv = [0, 0, 1]; // read-only 0-6, 0-1, 0-1
this.rgb = [1, 1, 1]; // read-only 0-1, 0-1, 0-1
this.minH = 0; // read-only 0-6
this.maxH = 6; // read-only 0-6
this.minS = 0; // read-only 0-1
this.maxS = 1; // read-only 0-1
this.minV = 0; // read-only 0-1
this.maxV = 1; // read-only 0-1
this.pickerOnfocus = true; // display picker on focus?
this.pickerMode = 'HSV'; // HSV | HVS
this.pickerPosition = 'bottom'; // left | right | top | bottom
this.pickerSmartPosition = true; // automatically adjust picker position when necessary
this.pickerButtonHeight = 20; // px
this.pickerClosable = false;
this.pickerCloseText = 'Close';
this.pickerButtonColor = 'ButtonText'; // px
this.pickerFace = 10; // px
this.pickerFaceColor = 'ThreeDFace'; // CSS color
this.pickerBorder = 1; // px
this.pickerBorderColor = 'ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight'; // CSS color
this.pickerInset = 1; // px
this.pickerInsetColor = 'ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow'; // CSS color
this.pickerZIndex = 10000;
for(var p in prop) {
if(prop.hasOwnProperty(p)) {
this[p] = prop[p];
}
}
this.hidePicker = function() {
if(isPickerOwner()) {
removePicker();
}
};
this.showPicker = function() {
if(!isPickerOwner()) {
var tp = jscolor.getElementPos(target); // target pos
var ts = jscolor.getElementSize(target); // target size
var vp = jscolor.getViewPos(); // view pos
var vs = jscolor.getViewSize(); // view size
var ps = getPickerDims(this); // picker size
var a, b, c;
switch(this.pickerPosition.toLowerCase()) {
case 'left': a=1; b=0; c=-1; break;
case 'right':a=1; b=0; c=1; break;
case 'top': a=0; b=1; c=-1; break;
default: a=0; b=1; c=1; break;
}
var l = (ts[b]+ps[b])/2;
// picker pos
if (!this.pickerSmartPosition) {
var pp = [
tp[a],
tp[b]+ts[b]-l+l*c
];
} else {
var pp = [
-vp[a]+tp[a]+ps[a] > vs[a] ?
(-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
tp[a],
-vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
(-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
(tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
];
}
drawPicker(pp[a], pp[b]);
}
};
this.importColor = function() {
if(!valueElement) {
this.exportColor();
} else {
if(!this.adjust) {
if(!this.fromString(valueElement.value, leaveValue)) {
styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
styleElement.style.color = styleElement.jscStyle.color;
this.exportColor(leaveValue | leaveStyle);
}
} else if(!this.required && /^\s*$/.test(valueElement.value)) {
valueElement.value = '';
styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
styleElement.style.color = styleElement.jscStyle.color;
this.exportColor(leaveValue | leaveStyle);
} else if(this.fromString(valueElement.value)) {
// OK
} else {
this.exportColor();
}
}
};
this.exportColor = function(flags) {
if(!(flags & leaveValue) && valueElement) {
var value = this.toString();
if(this.caps) { value = value.toUpperCase(); }
if(this.hash) { value = '#'+value; }
valueElement.value = value;
}
if(!(flags & leaveStyle) && styleElement) {
styleElement.style.backgroundImage = "none";
styleElement.style.backgroundColor =
'#'+this.toString();
styleElement.style.color =
0.213 * this.rgb[0] +
0.715 * this.rgb[1] +
0.072 * this.rgb[2]
< 0.5 ? '#FFF' : '#000';
}
if(!(flags & leavePad) && isPickerOwner()) {
redrawPad();
}
if(!(flags & leaveSld) && isPickerOwner()) {
redrawSld();
}
};
this.fromHSV = function(h, s, v, flags) { // null = don't change
if(h !== null) { h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h)); }
if(s !== null) { s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s)); }
if(v !== null) { v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v)); }
this.rgb = HSV_RGB(
h===null ? this.hsv[0] : (this.hsv[0]=h),
s===null ? this.hsv[1] : (this.hsv[1]=s),
v===null ? this.hsv[2] : (this.hsv[2]=v)
);
this.exportColor(flags);
};
this.fromRGB = function(r, g, b, flags) { // null = don't change
if(r !== null) { r = Math.max(0.0, Math.min(1.0, r)); }
if(g !== null) { g = Math.max(0.0, Math.min(1.0, g)); }
if(b !== null) { b = Math.max(0.0, Math.min(1.0, b)); }
var hsv = RGB_HSV(
r===null ? this.rgb[0] : r,
g===null ? this.rgb[1] : g,
b===null ? this.rgb[2] : b
);
if(hsv[0] !== null) {
this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0]));
}
if(hsv[2] !== 0) {
this.hsv[1] = hsv[1]===null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1]));
}
this.hsv[2] = hsv[2]===null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2]));
// update RGB according to final HSV, as some values might be trimmed
var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
this.rgb[0] = rgb[0];
this.rgb[1] = rgb[1];
this.rgb[2] = rgb[2];
this.exportColor(flags);
};
this.fromString = function(hex, flags) {
var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
if(!m) {
return false;
} else {
if(m[1].length === 6) { // 6-char notation
this.fromRGB(
parseInt(m[1].substr(0,2),16) / 255,
parseInt(m[1].substr(2,2),16) / 255,
parseInt(m[1].substr(4,2),16) / 255,
flags
);
} else { // 3-char notation
this.fromRGB(
parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
flags
);
}
return true;
}
};
this.toString = function() {
return (
(0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) +
(0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) +
(0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1)
);
};
function RGB_HSV(r, g, b) {
var n = Math.min(Math.min(r,g),b);
var v = Math.max(Math.max(r,g),b);
var m = v - n;
if(m === 0) { return [ null, 0, v ]; }
var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
return [ h===6?0:h, m/v, v ];
}
function HSV_RGB(h, s, v) {
if(h === null) { return [ v, v, v ]; }
var i = Math.floor(h);
var f = i%2 ? h-i : 1-(h-i);
var m = v * (1 - s);
var n = v * (1 - s*f);
switch(i) {
case 6:
case 0: return [v,n,m];
case 1: return [n,v,m];
case 2: return [m,v,n];
case 3: return [m,n,v];
case 4: return [n,m,v];
case 5: return [v,m,n];
}
}
function removePicker() {
delete jscolor.picker.owner;
document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
}
function drawPicker(x, y) {
if(!jscolor.picker) {
jscolor.picker = {
box : document.createElement('div'),
boxB : document.createElement('div'),
pad : document.createElement('div'),
padB : document.createElement('div'),
padM : document.createElement('div'),
sld : document.createElement('div'),
sldB : document.createElement('div'),
sldM : document.createElement('div'),
btn : document.createElement('div'),
btnS : document.createElement('span'),
btnT : document.createTextNode(THIS.pickerCloseText)
};
for(var i=0,segSize=4; i<jscolor.images.sld[1]; i+=segSize) {
var seg = document.createElement('div');
seg.style.height = segSize+'px';
seg.style.fontSize = '1px';
seg.style.lineHeight = '0';
jscolor.picker.sld.appendChild(seg);
}
jscolor.picker.sldB.appendChild(jscolor.picker.sld);
jscolor.picker.box.appendChild(jscolor.picker.sldB);
jscolor.picker.box.appendChild(jscolor.picker.sldM);
jscolor.picker.padB.appendChild(jscolor.picker.pad);
jscolor.picker.box.appendChild(jscolor.picker.padB);
jscolor.picker.box.appendChild(jscolor.picker.padM);
jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
jscolor.picker.btn.appendChild(jscolor.picker.btnS);
jscolor.picker.box.appendChild(jscolor.picker.btn);
jscolor.picker.boxB.appendChild(jscolor.picker.box);
}
var p = jscolor.picker;
// controls interaction
p.box.onmouseup =
p.box.onmouseout = function() { target.focus(); };
p.box.onmousedown = function() { abortBlur=true; };
p.box.onmousemove = function(e) {
if (holdPad || holdSld) {
holdPad && setPad(e);
holdSld && setSld(e);
if (document.selection) {
document.selection.empty();
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
}
dispatchImmediateChange();
}
};
p.padM.onmouseup =
p.padM.onmouseout = function() { if(holdPad) { holdPad=false; jscolor.fireEvent(valueElement,'change'); } };
p.padM.onmousedown = function(e) {
// if the slider is at the bottom, move it up
switch(modeID) {
case 0: if (THIS.hsv[2] === 0) { THIS.fromHSV(null, null, 1.0); }; break;
case 1: if (THIS.hsv[1] === 0) { THIS.fromHSV(null, 1.0, null); }; break;
}
holdPad=true;
setPad(e);
dispatchImmediateChange();
};
p.sldM.onmouseup =
p.sldM.onmouseout = function() { if(holdSld) { holdSld=false; jscolor.fireEvent(valueElement,'change'); } };
p.sldM.onmousedown = function(e) {
holdSld=true;
setSld(e);
dispatchImmediateChange();
};
// picker
var dims = getPickerDims(THIS);
p.box.style.width = dims[0] + 'px';
p.box.style.height = dims[1] + 'px';
// picker border
p.boxB.style.position = 'absolute';
p.boxB.style.clear = 'both';
p.boxB.style.left = x+'px';
p.boxB.style.top = y+'px';
p.boxB.style.zIndex = THIS.pickerZIndex;
p.boxB.style.border = THIS.pickerBorder+'px solid';
p.boxB.style.borderColor = THIS.pickerBorderColor;
p.boxB.style.background = THIS.pickerFaceColor;
// pad image
p.pad.style.width = jscolor.images.pad[0]+'px';
p.pad.style.height = jscolor.images.pad[1]+'px';
// pad border
p.padB.style.position = 'absolute';
p.padB.style.left = THIS.pickerFace+'px';
p.padB.style.top = THIS.pickerFace+'px';
p.padB.style.border = THIS.pickerInset+'px solid';
p.padB.style.borderColor = THIS.pickerInsetColor;
// pad mouse area
p.padM.style.position = 'absolute';
p.padM.style.left = '0';
p.padM.style.top = '0';
p.padM.style.width = THIS.pickerFace + 2*THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
p.padM.style.height = p.box.style.height;
p.padM.style.cursor = 'crosshair';
// slider image
p.sld.style.overflow = 'hidden';
p.sld.style.width = jscolor.images.sld[0]+'px';
p.sld.style.height = jscolor.images.sld[1]+'px';
// slider border
p.sldB.style.display = THIS.slider ? 'block' : 'none';
p.sldB.style.position = 'absolute';
p.sldB.style.right = THIS.pickerFace+'px';
p.sldB.style.top = THIS.pickerFace+'px';
p.sldB.style.border = THIS.pickerInset+'px solid';
p.sldB.style.borderColor = THIS.pickerInsetColor;
// slider mouse area
p.sldM.style.display = THIS.slider ? 'block' : 'none';
p.sldM.style.position = 'absolute';
p.sldM.style.right = '0';
p.sldM.style.top = '0';
p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2*THIS.pickerInset + 'px';
p.sldM.style.height = p.box.style.height;
try {
p.sldM.style.cursor = 'pointer';
} catch(eOldIE) {
p.sldM.style.cursor = 'hand';
}
// "close" button
function setBtnBorder() {
var insetColors = THIS.pickerInsetColor.split(/\s+/);
var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
p.btn.style.borderColor = pickerOutsetColor;
}
p.btn.style.display = THIS.pickerClosable ? 'block' : 'none';
p.btn.style.position = 'absolute';
p.btn.style.left = THIS.pickerFace + 'px';
p.btn.style.bottom = THIS.pickerFace + 'px';
p.btn.style.padding = '0 15px';
p.btn.style.height = '18px';
p.btn.style.border = THIS.pickerInset + 'px solid';
setBtnBorder();
p.btn.style.color = THIS.pickerButtonColor;
p.btn.style.font = '12px sans-serif';
p.btn.style.textAlign = 'center';
try {
p.btn.style.cursor = 'pointer';
} catch(eOldIE) {
p.btn.style.cursor = 'hand';
}
p.btn.onmousedown = function () {
THIS.hidePicker();
};
p.btnS.style.lineHeight = p.btn.style.height;
// load images in optimal order
switch(modeID) {
case 0: var padImg = 'hs.png'; break;
case 1: var padImg = 'hv.png'; break;
}
p.padM.style.backgroundImage = "url('"+jscolor.getDir()+"cross.gif')";
p.padM.style.backgroundRepeat = "no-repeat";
p.sldM.style.backgroundImage = "url('"+jscolor.getDir()+"arrow.gif')";
p.sldM.style.backgroundRepeat = "no-repeat";
p.pad.style.backgroundImage = "url('"+jscolor.getDir()+padImg+"')";
p.pad.style.backgroundRepeat = "no-repeat";
p.pad.style.backgroundPosition = "0 0";
// place pointers
redrawPad();
redrawSld();
jscolor.picker.owner = THIS;
document.getElementsByTagName('body')[0].appendChild(p.boxB);
}
function getPickerDims(o) {
var dims = [
2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[0] +
(o.slider ? 2*o.pickerInset + 2*jscolor.images.arrow[0] + jscolor.images.sld[0] : 0),
o.pickerClosable ?
4*o.pickerInset + 3*o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight :
2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[1]
];
return dims;
}
function redrawPad() {
// redraw the pad pointer
switch(modeID) {
case 0: var yComponent = 1; break;
case 1: var yComponent = 2; break;
}
var x = Math.round((THIS.hsv[0]/6) * (jscolor.images.pad[0]-1));
var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.pad[1]-1));
jscolor.picker.padM.style.backgroundPosition =
(THIS.pickerFace+THIS.pickerInset+x - Math.floor(jscolor.images.cross[0]/2)) + 'px ' +
(THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.cross[1]/2)) + 'px';
// redraw the slider image
var seg = jscolor.picker.sld.childNodes;
switch(modeID) {
case 0:
var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
for(var i=0; i<seg.length; i+=1) {
seg[i].style.backgroundColor = 'rgb('+
(rgb[0]*(1-i/seg.length)*100)+'%,'+
(rgb[1]*(1-i/seg.length)*100)+'%,'+
(rgb[2]*(1-i/seg.length)*100)+'%)';
}
break;
case 1:
var rgb, s, c = [ THIS.hsv[2], 0, 0 ];
var i = Math.floor(THIS.hsv[0]);
var f = i%2 ? THIS.hsv[0]-i : 1-(THIS.hsv[0]-i);
switch(i) {
case 6:
case 0: rgb=[0,1,2]; break;
case 1: rgb=[1,0,2]; break;
case 2: rgb=[2,0,1]; break;
case 3: rgb=[2,1,0]; break;
case 4: rgb=[1,2,0]; break;
case 5: rgb=[0,2,1]; break;
}
for(var i=0; i<seg.length; i+=1) {
s = 1 - 1/(seg.length-1)*i;
c[1] = c[0] * (1 - s*f);
c[2] = c[0] * (1 - s);
seg[i].style.backgroundColor = 'rgb('+
(c[rgb[0]]*100)+'%,'+
(c[rgb[1]]*100)+'%,'+
(c[rgb[2]]*100)+'%)';
}
break;
}
}
function redrawSld() {
// redraw the slider pointer
switch(modeID) {
case 0: var yComponent = 2; break;
case 1: var yComponent = 1; break;
}
var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.sld[1]-1));
jscolor.picker.sldM.style.backgroundPosition =
'0 ' + (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.arrow[1]/2)) + 'px';
}
function isPickerOwner() {
return jscolor.picker && jscolor.picker.owner === THIS;
}
function blurTarget() {
if(valueElement === target) {
THIS.importColor();
}
if(THIS.pickerOnfocus) {
THIS.hidePicker();
}
}
function blurValue() {
if(valueElement !== target) {
THIS.importColor();
}
}
function setPad(e) {
var mpos = jscolor.getRelMousePos(e);
var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
switch(modeID) {
case 0: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), 1 - y/(jscolor.images.pad[1]-1), null, leaveSld); break;
case 1: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), null, 1 - y/(jscolor.images.pad[1]-1), leaveSld); break;
}
}
function setSld(e) {
var mpos = jscolor.getRelMousePos(e);
var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
switch(modeID) {
case 0: THIS.fromHSV(null, null, 1 - y/(jscolor.images.sld[1]-1), leavePad); break;
case 1: THIS.fromHSV(null, 1 - y/(jscolor.images.sld[1]-1), null, leavePad); break;
}
}
function dispatchImmediateChange() {
if (THIS.onImmediateChange) {
var callback;
if (typeof THIS.onImmediateChange === 'string') {
callback = new Function (THIS.onImmediateChange);
} else {
callback = THIS.onImmediateChange;
}
callback.call(THIS);
}
}
var THIS = this;
var modeID = this.pickerMode.toLowerCase()==='hvs' ? 1 : 0;
var abortBlur = false;
var
valueElement = jscolor.fetchElement(this.valueElement),
styleElement = jscolor.fetchElement(this.styleElement);
var
holdPad = false,
holdSld = false;
var
leaveValue = 1<<0,
leaveStyle = 1<<1,
leavePad = 1<<2,
leaveSld = 1<<3;
// target
jscolor.addEvent(target, 'focus', function() {
if(THIS.pickerOnfocus) { THIS.showPicker(); }
});
jscolor.addEvent(target, 'blur', function() {
if(!abortBlur) {
window.setTimeout(function(){ abortBlur || blurTarget(); abortBlur=false; }, 0);
} else {
abortBlur = false;
}
});
// valueElement
if(valueElement) {
var updateField = function() {
THIS.fromString(valueElement.value, leaveValue);
dispatchImmediateChange();
};
jscolor.addEvent(valueElement, 'keyup', updateField);
jscolor.addEvent(valueElement, 'input', updateField);
jscolor.addEvent(valueElement, 'blur', blurValue);
valueElement.setAttribute('autocomplete', 'off');
}
// styleElement
if(styleElement) {
styleElement.jscStyle = {
backgroundImage : styleElement.style.backgroundImage,
backgroundColor : styleElement.style.backgroundColor,
color : styleElement.style.color
};
}
// require images
switch(modeID) {
case 0: jscolor.requireImage('hs.png'); break;
case 1: jscolor.requireImage('hv.png'); break;
}
jscolor.requireImage('cross.gif');
jscolor.requireImage('arrow.gif');
this.importColor();
}
};
jscolor.install();

0
app/widgets/Config/config.css

104
app/widgets/ConfigData/ConfigData.php

@ -0,0 +1,104 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ConfigData extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('configdata.css');
}
function ajaxClearRosterLink() {
$rd = new \modl\RosterLinkDAO();
$rd->clearRosterLink();
$this->refresh();
}
function ajaxClearMessage() {
$md = new \modl\MessageDAO();
$md->clearMessage();
$this->refresh();
}
function ajaxClearPost() {
$pd = new \modl\PostnDAO();
$pd->clearPost();
$this->refresh();
}
function refresh() {
$html = $this->prepareConfigData();
RPC::call('movim_fill', 'configdata', $html);
RPC::commit();
}
function prepareConfigData() {
$cd = new \modl\ContactDAO();
$stats = $cd->getStatistics();
$clearrosterlink = $this->genCallAjax('ajaxClearRosterLink');
$clearmessage = $this->genCallAjax('ajaxClearMessage');
$clearpost = $this->genCallAjax('ajaxClearPost');
$html = '
<form enctype="multipart/form-data" method="post" action="index.php" name="general">
<fieldset>
<legend>'.t('Cache').'</legend>
<div class="clear"></div>
<div class="element thin">
<label for="name">'.t('Post'). ' - '.$stats['Post'].'</label><br />
<a
type="button"
name="email"
class="button icon color red back"
onclick="'.$clearpost.'">'.t('Clear').'</a>
</div>
<div class="element thin">
<label for="name">'.t('Messages'). ' - '.$stats['Message'].'</label><br />
<a
type="button"
name="email"
class="button icon color red back"
onclick="'.$clearmessage.'">'.t('Clear').'</a>
</div>
<div class="element thin">
<label for="name">'.t('Contacts'). ' - '.$stats['RosterLink'].'</label><br />
<a
type="button"
class="button icon color red back"
onclick="'.$clearrosterlink.'">'.t('Clear').'</a>
</div>
</fieldset>
</form>';
return $html;
}
function build()
{
?>
<div class="tabelem padded" title="<?php echo t('Data'); ?>" id="configdata" >
<?php echo $this->prepareConfigData(); ?>
</div>
<?php
}
}

0
app/widgets/ConfigData/configdata.css

143
app/widgets/ContactCard/ContactCard.php

@ -0,0 +1,143 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactCard extends WidgetCommon
{
function WidgetLoad()
{
$this->addcss('contactcard.css');
$this->registerEvent('vcard', 'onVcard');
}
function onVcard($contact)
{
$html = $this->prepareContactCard($contact);
RPC::call('movim_fill', 'contactcard', $html);
}
function prepareContactCard($contact)
{
$gender = getGender();
$marital = getMarital();
$html .= '
<form name="vcard" id="vcardform"><br />
<h1>'.t('Profile').'</h1><br />
<fieldset>
<legend>'.t('General Informations').'</legend>';
if($this->testIsSet($contact->fn))
$html .= '<div class="element simple">
<label for="fn">'.t('Name').'</label>
<span>'.$contact->fn.'</span>
</div>';
if($this->testIsSet($contact->name))
$html .= '<div class="element simple">
<label for="name">'.t('Nickname').'</label>
<span>'.$contact->name.'</span>
</div>';
if(
$contact->date != '0000-00-00'
&& $contact->date != '1970-01-01'
&& $this->testIsSet($contact->date))
$html .= '<div class="element simple">
<label for="day">'.t('Date of Birth').'</label>
<span>'.date('j M Y',strtotime($contact->date)).'</span>
</div>';
if($contact->gender != 'N' && $this->testIsSet($contact->gender))
$html .= '<div class="element simple">
<label for="gender">'.t('Gender').'</label>
<span>'.$gender[$contact->gender].'</span>
</div>';
if($contact->marital != 'none' && $this->testIsSet($contact->marital))
$html .= '<div class="element simple">
<label for="marital">'.t('Marital Status').'</label>
<span>'.$marital[$contact->marital].'</span>
</div>';
if($this->testIsSet($contact->email))
$html .= '<div class="element simple">
<label for="url">'.t('Email').'</label>
<a target="_blank" href="mailto:'.$contact->email.'">'.$contact->email.'</a>
</div>';
if($this->testIsSet($contact->url))
$html .= '<div class="element simple">
<label for="url">'.t('Website').'</label>
<a target="_blank" href="'.$contact->url.'">'.$contact->url.'</a>
</div>';
if($this->testIsSet($contact->desc) && prepareString($contact->desc) != '')
$html .= '<div class="element large simple">
<label for="desc">'.t('About Me').'</label>
<span>'.prepareString($contact->desc).'</span>
</div>';
if($this->testIsSet($contact->adrlocality) ||
$this->testIsSet($contact->adrcountry)) {
$html .= '</fieldset>
<br />
<fieldset>
<legend>'.t('Geographic Position').'</legend>';
if($this->testIsSet($contact->adrlocality)) {
$locality .= '<div class="element simple">
<label for="desc">'.t('Locality').'</label>
<span>'.$contact->adrlocality;
if($contact->adrpostalcode != 0)
$locality .= ' ('.$contact->adrpostalcode.')';
$locality .= '</span>
</div>';
$html .= $locality;
}
if($this->testIsSet($contact->adrcountry))
$html .= '<div class="element simple">
<label for="desc">'.t('Country').'</label>
<span>'.$contact->adrcountry.'</span>
</div>';
}
$html .= '</fieldset>
<div class="config_button" onclick="'.$this->genCallWidget("ContactSummary","ajaxRefreshVcard", "'".$contact->jid."'").'"></div>
</form>';
return $html;
}
function build()
{
$cd = new modl\ContactDAO();
$contact = $cd->get($_GET['f']);
?>
<div class="tabelem protect red" title="<?php echo t('Profile'); ?>" id="contactcard" >
<?php
if(isset($contact))
echo $this->prepareContactCard($contact);
?>
</div>
<?php
}
}

8
app/widgets/ContactCard/contactcard.css

@ -0,0 +1,8 @@
#contactcard {
padding: 0px 1.5em;
}
#contactcard h1 {
padding: 0px;
padding-bottom: 20px;
}

214
app/widgets/ContactInfo/ContactInfo.php

@ -0,0 +1,214 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactInfo extends WidgetCommon
{
function WidgetLoad() {
}
function ajaxRemoveContact($jid) {
$r = new moxl\RosterRemoveItem();
$r->setTo($jid)
->request();
$p = new moxl\PresenceUnsubscribe();
$p->setTo($jid)
->request();
}
function prepareContactInfo()
{
$cd = new \modl\ContactDAO();
$c = $cd->getRosterItem($_GET['f']);
$html = '';
if(isset($c)) {
// Mood
if($c->mood) {
$moodarray = getMood();
$html .= '<h2>'.t('Mood').'</h2>';
$mood = '';
foreach(unserialize($c->mood) as $m)
$mood .= $moodarray[$m].',';
$html .= t("I'm ").substr($mood, 0, -1).'<br />';
}
if($c->tuneartist || $c->tunetitle) {
$html .= '<h2>'.t('Listening').'</h2>';
if($c->tuneartist)
$artist = $c->tuneartist. ' - ';
if($c->tunetitle)
$title = $c->tunetitle;
if($c->tunesource)
$album = t('on').' '.$c->tunesource;
$html .= $artist.$title.' '.$album;
}
// Last seen
if($c->delay && $c->delay != '0000-00-00 00:00:00') {
$html .= '<h2>'.t('Last seen').'</h2>';
$html .= prepareDate(strtotime($c->delay)).'<br />';
}
if($c->loclatitude != '' && $c->loclongitude != ''
|| $c->getPlace() != '') {
$html .= '
<h2>'.t('Location').'</h2>';
$html .= prepareDate(strtotime($c->loctimestamp)).'<br /><br />';
if($c->getPlace() != '')
$html .= $c->getPlace().'<br /><br />';
if(isset($c->loclatitude) && isset($c->loclongitude))
$html .= '
<div style="height: 250px;" id="map"></div>
<script type="text/javascript">
var map = L.map("map").setView(['.$c->loclatitude.' ,'.$c->loclongitude.'], 11);
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "",
maxZoom: 18
}).addTo(map);
var marker = L.marker(['.$c->loclatitude.' ,'.$c->loclongitude.']).addTo(map)
</script>';
}
// Client informations
if($c->node && $c->ver) {
$node = $c->node.'#'.$c->ver;
$cad = new \modl\CapsDAO();
$caps = $cad->get($node);
$clienttype =
array(
'bot' => t('Bot'),
'pc' => t('Desktop'),
'phone' => t('Phone'),
'handheld' => t('Phone'),
'web' => t('Web'),
);
if(isset($caps) && $caps->name != '' && $caps->type != '' ) {
$cinfos = '';
$cinfos .= $caps->name.' ('.$clienttype[$caps->type].')<br />';
$html .='<h2>'.t('Client Informations').'</h2>' . $cinfos;
}
}
// Chat button
if($c->jid != $this->user->getLogin()) {
$presences = getPresences();
$html .='<h2>'.t('Actions').'</h2>';
$ptoc = array(
1 => 'green',
2 => 'yellow',
3 => 'red',
4 => 'purple'
);
if(isset($c->presence) && !in_array($c->presence, array(5, 6))) {
$html .= '
<a
class="button color '.$ptoc[$c->presence].' icon chat"
style="float: left;"
id="friendchat"
onclick="'.$this->genCallWidget("Chat","ajaxOpenTalk", "'".$c->jid."'").'"
>
'.$presences[$c->presence].' - '.t('Chat').'
</a>';
}
}
$html .= '<div style="clear: both;"></div>';
$html .='
<a
class="button icon rm black"
style="margin: 1em 0px; display: block;"
id="friendremoveask"
onclick="
document.querySelector(\'#friendremoveyes\').style.display = \'block\';
document.querySelector(\'#friendremoveno\').style.display = \'block\';
this.style.display = \'none\'
"
>
'.t('Remove this contact').'
</a>
<a
class="button color green icon yes merged left';
if(!isset($c->presence) || $c->presence == 5)
$html .=' left';
$html .= '"
id="friendremoveyes"
style="margin: 1em 0px; float: left; display: none;"
onclick="'.$this->genCallAjax("ajaxRemoveContact", "'".$_GET['f']."'")
. 'this.className=\'button color green icon loading merged left\'; setTimeout(function() {location.reload(false)}, 2000);"
>
'.t('Yes').'
</a>
<a
class="button color red icon no merged right"
style="margin: 1em 0px; float: left; display: none;"
id="friendremoveno"
onclick="
document.querySelector(\'#friendremoveask\').style.display = \'block\';
document.querySelector(\'#friendremoveyes\').style.display = \'none\';
this.style.display = \'none\'
"
>
'.t('No').'
</a>';
} elseif($_GET['f'] != $this->user->getLogin()) {
$html .='<h2>'.t('Actions').'</h2>';
$html .='
<a
class="button color purple icon add"
onclick="'.$this->genCallWidget("Roster","ajaxAddContact", "'".$_GET['f']."'", "''")
. 'this.className=\'button color purple icon loading merged left\'; setTimeout(function() {location.reload(false)}, 2000);"
>
'.t('Invite this user').'
</a>';
}
return $html;
}
function build() {
echo $this->prepareContactInfo();
}
}

83
app/widgets/ContactManage/ContactManage.php

@ -0,0 +1,83 @@
<?php
/**
* @package Widgets
*
* @file ContactManage.php
* This file is part of MOVIM.
*
* @brief A little widget which manage the current contact
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 24 March 2013
*
* Copyright (C)2013 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactManage extends WidgetCommon
{
function WidgetLoad() {
}
public function ajaxContactManage($form) {
$rd = new \moxl\RosterUpdateItem();
$rd->setTo(echapJid($form['jid']))
->setName(htmlspecialchars($form['alias']))
->setGroup(htmlspecialchars($form['group']))
->request();
Notification::appendNotification(t('Contact updated'));
}
private function prepareContactManage($jid) {
$rd = new \modl\RosterLinkDAO();
$groups = $rd->getGroups();
$rl = $rd->get($jid);
$submit = $this->genCallAjax('ajaxContactManage', "movim_parse_form('manage')");
$html = '';
$html .= '<h2>'.t('Manage').'</h2>';
$html .= '
<form name="manage">';
$ghtml = '';
foreach($groups as $g)
$ghtml .= '<option value="'.$g.'"/>';
$html .= '
<input type="hidden" name="jid" value="'.$jid.'"/>
<div class="element large mini">
<input name="alias" id="alias" class="tiny" placeholder="'.t('Alias').'" value="'.$rl->rostername.'"/>
</div>
<div class="element large mini">
<datalist id="group" style="display: none;">
'.$ghtml.'
</datalist>
<input name="group" list="group" id="alias" class="tiny" placeholder="'.t('Group').'" value="'.$rl->group.'"/>
</div>
<a class="button black icon yes" onclick="'.$submit.'">'.t('Save').'</a>';
$html .= '
</form>';
return $html;
}
function build() {
?>
<div class="clear"></div>
<?php
if($_GET['f'] != $this->user->getLogin())
echo $this->prepareContactManage($_GET['f']);
}
}

75
app/widgets/ContactPubsubSubscription/ContactPubsubSubscription.php

@ -0,0 +1,75 @@
<?php
/**
* @package Widgets
*
* @file ContactPubsubSubscription.php
* This file is part of MOVIM.
*
* @brief The Group configuration widget
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 24 March 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactPubsubSubscription extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('groupsubscribedlist', 'onGroupSubscribedList');
$this->registerEvent('groupsubscribedlisterror', 'onGroupSubscribedListError');
}
function prepareList($list) {
if(is_array($list[0])){
$html = '<ul class="list">';
foreach($list as $item){
$html .= '<li><a href="?q=node&s='.$item[1].'&n='.$item[0].'">'.$item[2].'</a></li>';
}
$html .= '</ul>';
return $html;
}
Notification::appendNotification(t('No public groups found'), 'info');
}
function onGroupSubscribedList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'publicgroups', $html);
}
function onGroupSubscribedListError($error)
{
Notification::appendNotification($error, 'error');
}
function ajaxGetGroupSubscribedList($to){
$r = new moxl\PubsubSubscriptionListGetFriends();
$r->setTo($to)->request();
}
function build()
{
?>
<div class="tabelem padded protect red" title="<?php echo t('Public groups'); ?>" id="groupsubscribedlistfromfriend">
<a
class="button icon yes color green"
onclick="<?php echo $this->genCallAjax('ajaxGetGroupSubscribedList', "'".$_GET['f']."'"); ?> this.style.display = 'none'">
<?php echo t("Get public groups");?>
</a>
<div id="publicgroups"></div>
</div>
<?php
}
}
?>

104
app/widgets/ContactSummary/ContactSummary.php

@ -0,0 +1,104 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ContactSummary extends WidgetCommon
{
function WidgetLoad()
{
$this->addcss('contactsummary.css');
$this->registerEvent('vcard', 'onVcard');
}
function onVcard($contact)
{
$html = $this->prepareContactSummary($contact);
RPC::call('movim_fill', 'contactsummary', $html);
}
function ajaxRefreshVcard($jid)
{
$r = new moxl\VcardGet();
$r->setTo($jid)->request();
}
function prepareContactSummary($contact)
{
$gender = getGender();
$marital = getMarital();
// Contact avatar
$html .= '
<img src="'.$contact->getPhoto('l').'"/>
';
$presencetxt = getPresencesTxt();
// Contact general infos
$html .= '
<h1 class="'.$presencetxt[$contact->presence].'">'.$contact->getTrueName().'</h1>';
if($this->testIsSet($contact->name))
$html .= $contact->name.' ';
else
$html .= $contact->getTrueName().' ';
if($this->testIsSet($contact->url))
$html .= '<br /><a target="_blank" href="'.$contact->url.'">'.$contact->url.'</a>';
if($this->testIsSet($contact->status)) {
$html .= '
<div class="textbubble">
'.prepareString($contact->status).'
</div>';
}
return $html;
}
function build()
{
$cd = new modl\ContactDAO();
if($_GET['f'] == $this->user->getLogin())
$contact = $cd->get($this->user->getLogin());
else
$contact = $cd->getRosterItem($_GET['f']);
if(!isset($contact))
$contact = $cd->get($_GET['f']);
?>
<div id="contactsummary">
<?php
if(isset($contact->photobin)) {
echo $this->prepareContactSummary($contact);
}
else {
$contact = new modl\Contact();
echo $this->prepareContactSummary($contact);
?>
<script type="text/javascript">setTimeout("<?php $this->callAjax('ajaxRefreshVcard', "'".$_GET['f']."'");?>", 1000);</script>
<?php } ?>
</div>
<?php
}
}

28
app/widgets/ContactSummary/contactsummary.css

@ -0,0 +1,28 @@
#contactsummary {
background-color: #272727;
margin: -1em;
padding: 1em;
line-height: 1.5em;
}
#contactsummary h1 {
color: white;
line-height: 1.5em;
padding: 0px;
margin: 0.5em 0em;
}
#contactsummary img {
width: 200px;
height: auto;
display: block;
margin: -1em;
margin-bottom: 1em;
}
#contactsummary .textbubble {
margin: -1em;
margin-top: 1em;
background-color: #171717;
padding: 1em;
}

160
app/widgets/Explore/Explore.php

@ -0,0 +1,160 @@
<?php
class Explore extends WidgetCommon {
function WidgetLoad()
{
$this->addcss('explore.css');
}
function ajaxSearchContacts($form) {
$html = $this->prepareContacts($form);
RPC::call('movim_fill', 'contactsresult', $html);
RPC::commit();
}
function colorSearch($search, $text) {
return str_replace(
$search,
'<span style="background-color: yellow;">'.$search.'</span>',
$text
);
}
function prepareServers() {
$nd = new \modl\NodeDAO();
$servers = $nd->getServers();
$html = '<ul class="list">';
foreach($servers as $s) {
$html .= '
<li>
<a href="'.Route::urlize('server', $s->serverid).'">'.
$s->serverid. '
<span class="tag">'.$s->number.'</span>
</a>
</li>';
}
$html .= '</ul>';
return $html;
//var_dump($nd->getServers());
}
function prepareContacts($form = false) {
/*if(!$form){
$where = array('public' => 1);
}
else{
$where = array(
'public' => 1,
array(
'fn%' => '%'.$form['search'].'%',
'|jid%' => '%'.$form['search'].'%',
'|name%' => '%'.$form['search'].'%',
'|email%' => '%'.$form['search'].'%',
'|nickname%' => '%'.$form['search'].'%'
)
);
}
$users_limit = 20;
$gender = getGender();
$marital = getMarital();
$query = Contact::query()->select()
->where($where)
//s->orderby('id', true)
->limit(0, $users_limit);
$users = Contact::run_query($query);
$html = '
<div class="posthead">
<!--<ul class="filters">
<li class="on">'.t('Last registered').'</li>
</ul>-->
<div class="clear"></div>
</div>';*/
$cd = new \modl\ContactDAO();
$users = array_reverse($cd->getAllPublic());
$gender = getGender();
$marital = getMarital();
foreach($users as $user) {
$html .= '
<div class="post">
<a href="?q=friend&f='.$user->jid.'">
<img class="avatar" src="'.$user->getPhoto('m').'"/>
<div class="postbubble">
<span class="name">'.
$user->getTrueName().'
</span>
<span class="asv">'.
$user->getAge().' '.
$gender[$user->gender].' '.
$marital[$user->marital].'
</span>
<div
class="content"
style="
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 1.5em;
"
>'.prepareString($user->desc).'</div>
</div>
</a>
</div>
';
}
return $html;
}
function build()
{
?>
<div id="explore">
<!--<form name="searchform" style="margin: 1em 1.5em;" onsubmit="event.preventDefault();">
<div class="element" style="min-height: 0em;">
<input
id="addjid"
class="tiny"
name="search"
placeholder="<?php echo t('Search a contact'); ?>"
onkeypress="if(event.keyCode==13){<?php $this->callAjax("ajaxSearchContacts","movim_parse_form('searchform')"); ?>}"
/>
</div>
<div class="element" style="min-height: 0em; margin-top: 5px;">
<a
class="button icon submit"
href="#"
onclick="<?php $this->callAjax("ajaxSearchContacts","movim_parse_form('searchform')"); ?> "
style="">
<?php echo t('Search'); ?>
</a>
</div>
</form>-->
<div id="serverresult" class="paddedtop">
<h2><?php echo t('Discussion Servers'); ?></h2>
<?php echo $this->prepareServers(); ?>
</div>
<div class="paddedtopbottom">
<h2><?php echo t('Last registered'); ?></h2>
</div>
<div id="contactsresult">
<?php echo $this->prepareContacts(); ?>
</div>
</div>
<?php
}
}

4
app/widgets/Explore/explore.css

@ -0,0 +1,4 @@
#explore {
margin-bottom: 2em;
min-height: 600px;
}

213
app/widgets/Feed/Feed.php

@ -0,0 +1,213 @@
<?php
class Feed extends WidgetCommon {
private $_feedsize = 10;
function WidgetLoad()
{
$this->addcss('feed.css');
$this->addjs('feed.js');
$this->registerEvent('post', 'onStream');
$this->registerEvent('postdeleted', 'onPostDelete');
$this->registerEvent('postdeleteerror', 'onPostDeleteError');
$this->registerEvent('comment', 'onComment');
$this->registerEvent('nocomment', 'onNoComment');
$this->registerEvent('nocommentstream', 'onNoCommentStream');
$this->registerEvent('commentpublisherror', 'onCommentPublishError');
$this->registerEvent('stream', 'onStream');
$this->registerEvent('postpublished', 'onPostPublished');
$this->registerEvent('postpublisherror', 'onPostPublishError');
$this->registerEvent('nodecreated', 'onNodeCreated');
$this->registerEvent('nodecreationerror', 'onNodeCreationError');
$this->registerEvent('config', 'onConfig');
$this->cached = false;
}
function onConfig(array $data)
{
$this->user->setConfig($data);
RPC::call('movim_fill', 'feedhead', $this->prepareHead());
}
function onNodeCreated() {
$config = $this->user->getConfig();
$config['feed'] = 'created';
$s = new moxl\StorageSet();
$s->setXmlns('movim:prefs')
->setData(serialize($config))
->request();
}
function onNodeCreationError() {
$config = $this->user->getConfig();
$config['feed'] = 'error';
$s = new moxl\StorageSet();
$s->setXmlns('movim:prefs')
->setData(serialize($config))
->request();
Notification::appendNotification(
t("Your server doesn't support post publication, you can only read contact's feeds"),
'error');
}
function onCommentPublishError() {
$html =
'<div class="message error">'.
t("Comment publication error").'
</div>';
RPC::call('movim_fill', 'feednotifs', $html);
}
function onPostPublished($post) {
$pd = new \modl\PostnDAO();
$pl = $pd->getFeed(-1, $this->_feedsize);
$html = $this->preparePosts($pl);
RPC::call('createCommentNode', $post->nodeid);
RPC::call('movim_fill', 'feedcontent', $html);
}
function ajaxCreateCommentNode($parentid) {
$n = new moxl\MicroblogCommentCreateNode();
$n->setTo($this->user->getLogin())
->setParentId($parentid)
->request();
}
function onPostPublishError($error) {
Notification::appendNotification(t('An error occured : ').$error, 'error');
}
function prepareHead() {
$html = '';
global $session;
if($session['config']['config'] == false) {
$html .=
'<div class="message warning" style="margin: 1.5em;">'.
t("Your server doesn't support post publication, you can only read contact's feeds").
'</div>';
} elseif(!isset($session['config']['feed'])) {
$html .= '
<div id="feednotifs">
<div class="message info">'.
t("Creating your feed...").
'</div>
</div>
<script type="text/javascript">'.
$this->genCallAjax('ajaxCreateNode').
'</script>';
} else {
$html .= '
<script type="text/javascript">
function createCommentNode(parentid) {'.
$this->genCallAjax('ajaxCreateCommentNode', 'parentid[0]').
'}
</script>
'.$this->prepareSubmitForm($this->user->getLogin(), 'urn:xmpp:microblog:0').'
<div id="feednotifs"></div>';
}
return $html;
}
function prepareFeed($start) {
$pd = new \modl\PostnDAO();
$pl = $pd->getFeed($start+1, $this->_feedsize);
$html = $this->preparePosts($pl);
// We ask for the HTML of all the posts
$next = $start + $this->_feedsize;
if(sizeof($pl) > $this->_feedsize-1 && $html != '') {
$html .= '
<div class="post">
<div
class="older"
onclick="'.$this->genCallAjax('ajaxGetFeed', "'".$next."'").'; this.parentNode.style.display = \'none\'">'.
t('Get older posts').'
</div>
</div>';
}
return $html;
}
function ajaxGetFeed($start) {
$html = $this->prepareFeed($start);
RPC::call('movim_append', 'feedcontent', $html);
RPC::commit();
}
function onStream($payload) {
$html = '';
$html = $this->prepareFeed(-1);
if($html == '')
$html = '
<div class="message info" style="margin: 1.5em; margin-top: 0em;">'.
t("Your feed cannot be loaded.").'
</div>';
RPC::call('movim_fill', 'feedcontent', $html);
RPC::commit();
}
function ajaxCreateNode()
{
$p = new moxl\MicroblogCreateNode();
$p->setTo($this->user->getLogin())
->request();
}
function build()
{
?>
<div class="tabelem" title="<?php echo t('Feed'); ?>" id="feed">
<div id="feedhead">
<?php
echo $this->prepareHead();
?>
</div>
<div class="posthead">
<a
class="button color merged left icon blog"
href="<?php echo Route::urlize('blog',$this->user->getLogin()); ?>"
target="_blank">
<?php echo t('Blog'); ?>
</a><a
class="button color orange merged right icon feed"
href="<?php echo Route::urlize('feed',$this->user->getLogin()); ?>"
target="_blank">
<?php echo t('Feed'); ?> (Atom)
</a>
<ul class="filters">
<li class="on" onclick="showPosts(this, false);"><?php echo t('All');?></li>
<li onclick="showPosts(this, true);"><?php echo t('My Posts');?></li>
</ul>
</div>
<div id="feedcontent">
<?php
echo $this->prepareFeed(-1);
?>
</div>
</div>
<?php
}
}

1
app/widgets/Feed/feed.css

@ -0,0 +1 @@

21
app/widgets/Feed/feed.js

@ -0,0 +1,21 @@
function showPosts(n, me) {
feed = document.querySelector('#feedcontent');
posts = feed.children;
for(i = 0; i < posts.length; i++) {
console.log(posts.item(i).className);
if(me == true) {
if(posts.item(i).className.split(' ', 2)[1] != 'me')
posts.item(i).style.display = 'none';
}
else
posts.item(i).style.display = 'block';
}
tabs = n.parentNode.children;
for(i = 0; i < tabs.length; i++)
tabs[i].className = '';
n.className = 'on';
}

74
app/widgets/Help/Help.php

@ -0,0 +1,74 @@
<?php
/**
* @package Widgets
*
* @file Vcard.php
* This file is part of MOVIM.
*
* @brief A widget which display some help
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 3 may 2012
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Help extends WidgetBase
{
function WidgetLoad() {
}
function build()
{
?>
<div class="tabelem paddedtop" title="<?php echo t('Help'); ?>" id="help">
<h2><?php echo t('What is Movim?'); ?></h2>
<p><?php echo t('Visit the page %s What is Movim ? %s to know more about the project, its aims and understand how it works.',
'<a href="http://wiki.movim.eu/whoami" target="_blank">', '</a>'); ?></p>
<h2><?php echo t('What do the little banners refer to ?'); ?></h2>
<center>
<div style="width: 60px; height: 50px; display: inline-block;" class="protect white"></div>
<div style="width: 60px; height: 50px; display: inline-block;" class="protect green"></div>
<div style="width: 60px; height: 50px; display: inline-block;" class="protect orange"></div>
<div style="width: 60px; height: 50px; display: inline-block;" class="protect red"></div>
<div style="width: 60px; height: 50px; display: inline-block;" class="protect black"></div>
</center>
<p><?php echo t('Thanks to these five little banners, you can quickly identitfy the level of confdentiality applied to the information you provide.'); ?></p>
<p>
<ul class="clean">
<li><?php echo t('White, only you can see the information'); ?></li>
<li><?php echo t('Green, you have chosen some contacts who can see your information'); ?></li>
<li><?php echo t('Orange, all your contact list can see your information'); ?></li>
<li><?php echo t('Red, everybody in the XMPP network can see your information'); ?></li>
<li><?php echo t('Black, the whole Internet can see your information'); ?></li>
</ul>
</p>
<h2><?php echo t("Some features are missing/I can't do everything I used to do on other social networks"); ?></h2>
<p><?php echo t("Although Movim is evolving fast, many (many) features are missing. Be patient ;). You can have a look %s at next versions's roadmaps %s to know if the one you want is on its way.", '<a href="http://wiki.movim.eu/dev:roadmaps" target="_blank">', '</a>'); ?>
<?php echo t("Don't forget that Movim is an open source project, a helping hand is always welcome (see %s Can I participate %s)",
'<a href="http://wiki.movim.eu/whoami#how_can_i_help" target="_blank">', '</a>'); ?></p>
<h2><?php echo t("I can't find the answer to my question here"); ?></h2>
<p><?php echo t('Go to the %s to the Frequently Asked Questions %s or come ask your question on the official chatroom %s or via our mailing-list (%s see the dedicated page %s).',
'<a href="http://wiki.movim.eu/whoami#faq" target="_blank">', '</a>',
'<a href="xmpp:movim@conference.movim.eu" target="_blank">movim@conference.movim.eu</a>',
'<a href="http://wiki.movim.eu/mailing_list" target="_blank">', '</a>'); ?></p>
</div>
<?php
}
}

0
app/widgets/Help/help.css

49
app/widgets/Log/Log.php

@ -0,0 +1,49 @@
<?php
/**
* @package Widgets
*
* @file Log.php
* This file is part of MOVIM.
*
* @brief The log widget.
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Log extends WidgetBase
{
function widgetLoad()
{
$this->addcss('log.css');
$this->registerEvent('allEvents', 'onEvent');
}
function build()
{
?>
<div id="log">
<h3><?php echo t('Debug console'); ?></h3>
<div id="log_content">
</div>
</div>
<?php
}
function onEvent($data)
{
RPC::call('movim_fill',
'log_content',
serialize($data));
}
}
?>

29
app/widgets/Log/log.css

@ -0,0 +1,29 @@
/* Logs style */
#log {
background-color: rgba(0, 0, 0, 0.8);
color: white;
/* height: 350px;*/
overflow: hidden;
font-size: 10px;
padding: 5px;
position: fixed;
bottom: 0;
left: 0;
width: 300px;
z-index: 3;
height: 12px;
}
#log:hover {
position: fixed;
top: 0px;
right: 0px;
width: 40%;
height: 100%;
border-left: 1px solid black;
}
#log span {
color: green;
}

335
app/widgets/Login/Login.php

@ -0,0 +1,335 @@
<?php
/**
* @package Widgets
*
* @file Login.php
* This file is part of MOVIM.
*
* @brief The login form.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 07 December 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Login extends WidgetBase {
function WidgetLoad()
{
$this->addcss('login.css');
$this->addjs('login.js');
$this->registerEvent('config', 'onConfig');
}
function onConfig(array $data)
{
$this->user->setConfig($data);
}
private function displayWarning($warning, $htmlonly = false)
{
if($warning != false) {
switch ($warning) {
case 'noaccount':
$warning = '
<div class="message warning">
'.t('Wrong username').'
</div> ';
break;
case 'invalidjid':
$warning = '
<div class="message warning">
'.t('Invalid JID').'
</div> ';
break;
case 'errormechanism':
$warning = '
<div class="message error">
'.t('Authentication mechanism not supported by Movim').'
</div> ';
break;
case 'errorchallenge':
$warning = '
<div class="message error">
'.t('Empty Challenge from the server').'
</div> ';
break;
case 'dnsdomain':
$warning = '
<div class="message error">
'.t('XMPP Domain error, your account is not a correct Jabber ID').'
</div> ';
break;
case 'datamissing':
$warning = '
<div class="message error">
'.t('Some data are missing !').'
</div> ';
break;
case 'wrongpass':
$warning = '
<div class="message warning">
'.t('Wrong password').'
</div> ';
break;
case 'failauth':
$warning = '
<div class="message warning">
'.t('The XMPP authentification failed').'
</div> ';
break;
case 'bosherror':
$warning = '
<div class="message error">
'.t('The current BOSH URL in invalid').'
</div> ';
break;
case 'internal':
$warning = '
<div class="message error">
'.t('Internal server error').'
</div> ';
break;
case 'session':
$warning = '
<div class="message error">
'.t('Session error').'
</div> ';
break;
case 'acccreated':
$warning = '
<div class="message success">
'.t('Account successfully created').'
</div> ';
break;
case 'wrongaccount':
$warning = '
<div class="message error">
'.t('Movim failed to authenticate. You entered wrong data').'
</div> ';
break;
case 'serverunauthorized':
$warning = '
<div class="message warning">
'.t('Your XMPP server is unauthorized').'
</div>';
case 'mecerror':
$warning = '
<div class="message warning">
'.t('The server takes too much time to repond').'
</div>';
break;
}
if($htmlonly)
return $warning;
else {
RPC::call('movim_fill', 'warning', $warning);
RPC::call('loginButtonSet', t("Come in!"));
RPC::commit();
exit;
}
}
}
function ajaxLogin($element)
{
// We get the Server Configuration
$serverconfig = Conf::getServerConf();
$warning = false;
// Empty input test
foreach($element as $value) {
if($value == NULL || $value == '') {
$warning = 'datamissing';
}
}
$this->displayWarning($warning);
// Correct email test
if(!filter_var($element['login'], FILTER_VALIDATE_EMAIL))
$warning = 'invalidjid';
$this->displayWarning($warning);
// Check whitelisted server
if(
$serverconfig['xmppWhiteList'] != '' &&!
in_array(
end(
explode('@', $element['login'])
),
explode(',',$serverconfig['xmppWhiteList'])
)
)
$warning = 'serverunauthorized';
$this->displayWarning($warning);
// Correct XMPP account test
$login_arr = explode('@', $element['login']);
$user = $login_arr[0];
$host = $login_arr[1];
$dns = dns_get_record('_xmpp-client._tcp.'.$login_arr[1]);
if(isset($dns[0]['target']) && $dns[0]['target'] != null)
$domain = $dns[0]['target'];
else {
$domain = $host;
//$warning = 'dnsdomain';
}
$this->displayWarning($warning);
global $session;
if($s != false) {
$session = $sess->get('session');
}
else {
$session = array(
'rid' => 1,
'sid' => 0,
'id' => 0,
'url' => $serverconfig['boshUrl'],
'port'=> 5222,
'host'=> $host,
'domain' => $domain,
'ressource' => 'moxl'.substr(md5(date('c')), 3, 6),
'user' => $user,
'password' => $element['pass'],
'proxyenabled' => $serverconfig['proxyEnabled'],
'proxyurl' => $serverconfig['proxyURL'],
'proxyport' => $serverconfig['proxyPort'],
'proxyuser' => $serverconfig['proxyUser'],
'proxypass' => $serverconfig['proxyPass']);
}
$sess = Session::start(APP_NAME);
$sess->set('session', $session);
// BOSH + XMPP connexion test
$warning = moxl\login();
if($warning != 'OK')
$this->displayWarning($warning);
$pd = new modl\PresenceDAO();
$pd->clearPresence($element['login']);
RPC::call('enterMovim', Route::urlize('main'));
RPC::commit();
}
function ajaxGetConfig()
{
$s = new moxl\StorageGet();
$s->setXmlns('movim:prefs')
->request(); $evt = new \Event();
$evt->runEvent('nostream');
}
function build()
{
$submit = $this->genCallAjax('ajaxLogin', "movim_parse_form('login')");
?>
<div id="loginpage" class="fadeDown">
<?php
if(!BROWSER_COMP) {
echo '
<div class="message warning">
'.t('Your web browser is too old to use with Movim.').'
</div> ';
} else {
?>
<form
name="login"
id="connectform"
autocomplete="on"
target="passwordiframe"
method="POST"
action="blank.php"
onkeypress="
if(event.keyCode == 13) {
<?php echo $submit; ?> loginButtonSet('<?php echo t('Connecting...');?>', true); this.onclick=null;}">
<div class="element">
<input type="email" name="login" id="login" autofocus required
placeholder="<?php echo t("My address"); ?>"/>
</div>
<div class="element">
<input type="password" name="pass" id="pass" required
placeholder="<?php echo t("Password"); ?>"/>
</div>
<div class="element">
<a
class="button color green icon yes"
onclick="<?php echo $submit; ?> loginButtonSet('<?php echo t('Connecting...');?>', true); this.onclick=null;"
id="submit"
name="submit"><?php echo t("Come in!"); ?></a>
</div>
<input style="display: none;" type="submit" id="submitb" name="submitb" value="submit"/>
<div class="clear"></div>
<ul id="loginhelp">
<li id="jabber"><?php echo t('You can login using your favorite Jabber account')?>
<a href="#" onclick="fillExample('demonstration@movim.eu', 'demonstration');">
<?php echo t('or with our demonstration account'); ?>
</a>
</li>
<li id="gmail">
<?php echo t('%sGmail accounts are also compatible%s but are not fully supported',
'<a href="#" onclick="fillExample(\'your.id@gmail.com \', \'\');">', '</a>')?>
</li>
<li id="facebook">
<?php echo t('You can login with Facebook (chat only) using %s your.id@chat.facebook.com %s and your password',
'<a href="#" onclick="fillExample(\'your.id@chat.facebook.com \', \'\');">', '</a>'); ?>
</li>
</ul>
<iframe id="passwordiframe" name="passwordiframe" style="display: none;"></iframe>
<div id="warning"><?php echo $this->displayWarning($_GET['err'], true); ?></div>
<div class="infos">
<?php
$pop = count(scandir(USERS_PATH))-3;
echo t('Population').' '.$pop.' • ';
?>
<?php echo t('No account yet ?'); ?>
<a href="<?php echo Route::urlize('account'); ?>">
<?php echo t('Create one !'); ?>
</a>
</div>
<div class="clear"></div>
</form>
<?php
}
?>
<div class="admin">
<a href="<?php echo Route::urlize('admin'); ?>">
<?php echo t('Administration'); ?>
</a>
</div>
</div>
<?php
}
}

BIN
app/widgets/Login/img/beaker.png

After

Width: 22  |  Height: 22  |  Size: 316 B

BIN
app/widgets/Login/img/envelope.png

After

Width: 22  |  Height: 22  |  Size: 336 B

BIN
app/widgets/Login/img/facebook.png

After

Width: 22  |  Height: 22  |  Size: 259 B

BIN
app/widgets/Login/img/jabber.png

After

Width: 22  |  Height: 22  |  Size: 616 B

BIN
app/widgets/Login/img/logo.png

After

Width: 290  |  Height: 95  |  Size: 7.0 KiB

512
app/widgets/Login/img/logo.svg

@ -0,0 +1,512 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="720.02863"
height="239.72249"
id="svg3120"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="logo.svg"
inkscape:export-filename="/var/www/movim-moxl/system/Widget/widgets/Login/img/logo.png"
inkscape:export-xdpi="36.591881"
inkscape:export-ydpi="36.591881">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1014"
id="namedview125"
showgrid="true"
inkscape:zoom="0.82"
inkscape:cx="324.57775"
inkscape:cy="93.049946"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg3120"
fit-margin-top="10"
fit-margin-left="10"
fit-margin-right="10"
fit-margin-bottom="10">
<inkscape:grid
type="xygrid"
id="grid3136"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
originx="10px"
originy="-17.777509px" />
</sodipodi:namedview>
<defs
id="defs3122">
<filter
x="-0.0078858454"
y="-0.1095808"
width="1.0157717"
height="1.2191616"
color-interpolation-filters="sRGB"
id="filter4356">
<feGaussianBlur
id="feGaussianBlur4358"
stdDeviation="2.2993777" />
</filter>
<filter
color-interpolation-filters="sRGB"
id="filter4652">
<feGaussianBlur
id="feGaussianBlur4654"
stdDeviation="2.7592533" />
</filter>
<filter
color-interpolation-filters="sRGB"
id="filter4656">
<feGaussianBlur
id="feGaussianBlur4658"
stdDeviation="2.7592533" />
</filter>
<filter
color-interpolation-filters="sRGB"
id="filter4660">
<feGaussianBlur
id="feGaussianBlur4662"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.23967367"
y="-0.13329828"
width="1.4793473"
height="1.2665966"
color-interpolation-filters="sRGB"
id="filter4664">
<feGaussianBlur
id="feGaussianBlur4666"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.4383243"
y="-0.18749084"
width="1.8766485"
height="1.3749816"
color-interpolation-filters="sRGB"
id="filter4668">
<feGaussianBlur
id="feGaussianBlur4670"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.19697919"
y="-0.18120626"
width="1.3939584"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4672">
<feGaussianBlur
id="feGaussianBlur4674"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.13078998"
y="-0.18749084"
width="1.26158"
height="1.3749816"
color-interpolation-filters="sRGB"
id="filter4676">
<feGaussianBlur
id="feGaussianBlur4678"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.37426057"
y="-0.13802518"
width="1.7485212"
height="1.2760504"
color-interpolation-filters="sRGB"
id="filter4680">
<feGaussianBlur
id="feGaussianBlur4682"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.19658127"
y="-0.18120626"
width="1.3931625"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4684">
<feGaussianBlur
id="feGaussianBlur4686"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.24145845"
y="-0.18464468"
width="1.482917"
height="1.3692894"
color-interpolation-filters="sRGB"
id="filter4688">
<feGaussianBlur
id="feGaussianBlur4690"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.64871836"
y="-0.13239136"
width="2.2974367"
height="1.2647827"
color-interpolation-filters="sRGB"
id="filter4692">
<feGaussianBlur
id="feGaussianBlur4694"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.22949941"
y="-0.18120626"
width="1.4589988"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4696">
<feGaussianBlur
id="feGaussianBlur4698"
stdDeviation="2.7592533" />
</filter>
<filter
x="-4.8653712"
y="-0.13571514"
width="10.730742"
height="1.2714303"
color-interpolation-filters="sRGB"
id="filter4700">
<feGaussianBlur
id="feGaussianBlur4702"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.21528263"
y="-0.18120626"
width="1.4305654"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4704">
<feGaussianBlur
id="feGaussianBlur4706"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.19697925"
y="-0.18120626"
width="1.3939584"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4708">
<feGaussianBlur
id="feGaussianBlur4710"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.2476024"
y="-0.18120626"
width="1.4952048"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4712">
<feGaussianBlur
id="feGaussianBlur4714"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.2476024"
y="-0.18120626"
width="1.4952048"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4716">
<feGaussianBlur
id="feGaussianBlur4718"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.2476024"
y="-0.18120626"
width="1.4952048"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4720">
<feGaussianBlur
id="feGaussianBlur4722"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.22949941"
y="-0.18120626"
width="1.4589988"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4724">
<feGaussianBlur
id="feGaussianBlur4726"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.2396742"
y="-0.13329828"
width="1.4793484"
height="1.2665966"
color-interpolation-filters="sRGB"
id="filter4728">
<feGaussianBlur
id="feGaussianBlur4730"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.21528256"
y="-0.18120626"
width="1.4305651"
height="1.3624125"
color-interpolation-filters="sRGB"
id="filter4732">
<feGaussianBlur
id="feGaussianBlur4734"
stdDeviation="2.7592533" />
</filter>
<filter
x="-4.8653712"
y="-0.13571514"
width="10.730742"
height="1.2714303"
color-interpolation-filters="sRGB"
id="filter4736">
<feGaussianBlur
id="feGaussianBlur4738"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.2396742"
y="-0.13329828"
width="1.4793484"
height="1.2665966"
color-interpolation-filters="sRGB"
id="filter4740">
<feGaussianBlur
id="feGaussianBlur4742"
stdDeviation="2.7592533" />
</filter>
<filter
x="-0.44148052"
y="-0.044413414"
width="1.882961"
height="1.0888268"
color-interpolation-filters="sRGB"
id="filter4744">
<feGaussianBlur
id="feGaussianBlur4746"
stdDeviation="2.7592533" />
</filter>
</defs>
<metadata
id="metadata3125">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(11.136359,11.13637)"
id="layer2-8-2-1"
style="fill:#ffffff">
<g
transform="translate(-346.29868,-584.40759)"
id="g4007-8-3-3-4"
style="fill:#ffffff">
<path
d="m 816.15625,622.375 0,110 10,0 0,-110 -10,0 z"
id="path3788-7-4-8-4"
style="font-size:182.75830078000001322px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Raleway;-inkscape-font-specification:Raleway Bold"
inkscape:connector-curvature="0" />
<path
d="m 825,289.09448 a 5,5 0 1 1 -10,0 5,5 0 1 1 10,0 z"
id="path3850-4-4-1-5"
style="fill:#ffffff;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0"
transform="matrix(1.5,0,0,1.5,-408.83774,157.1295)" />
</g>
<g
transform="translate(-346.13636,-584.40759)"
id="text4011-1-2-7-0"
style="font-size:68.05427551000001074px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Raleway;-inkscape-font-specification:Raleway Light">
<path
d="m 371.22638,802.31317 -15.03999,-20.21212 -9.59565,8.71095 0,11.50117 -1.36109,0 0,-49.67962 1.36109,0 0,36.34098 24.09121,-21.84542 1.83747,0 -15.31222,14.01918 15.65249,21.16488 -1.63331,0"
id="path8174-0-4-5-0"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 377.8957,802.31317 0,-35.18406 1.36109,0 0,35.18406 -1.36109,0 m 0,-44.43944 0,-4.35547 1.36109,0 0,4.35547 -1.36109,0"
id="path8176-2-1-4-4"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 387.10961,784.75517 c 0,-2.3592 0.38564,-4.62767 1.15693,-6.80543 0.81664,-2.22308 1.95088,-4.17397 3.40271,-5.85267 1.45182,-1.72401 3.17586,-3.08509 5.17213,-4.08325 2.04161,-1.04347 4.26471,-1.56522 6.66932,-1.56525 3.76564,3e-5 6.71466,0.74863 8.84705,2.24579 2.13234,1.45186 3.78832,3.33469 4.96796,5.6485 l -1.29303,0.47638 c -1.31574,-2.44992 -3.06247,-4.21933 -5.24018,-5.30823 -2.17776,-1.1342 -4.60503,-1.70132 -7.2818,-1.70136 -2.40461,4e-5 -4.53697,0.52179 -6.39711,1.56525 -1.86016,0.99816 -3.4254,2.31388 -4.69574,3.94715 -1.27036,1.58796 -2.2458,3.40274 -2.92634,5.44434 -0.68054,1.99628 -1.02081,3.99254 -1.02081,5.98878 0,2.22312 0.40832,4.35549 1.22498,6.3971 0.81664,1.99627 1.92819,3.78836 3.33466,5.37629 1.40644,1.54257 3.06243,2.79023 4.96796,3.74298 1.9055,0.90739 3.94713,1.36109 6.12488,1.36109 1.08885,0 2.29114,-0.15879 3.60688,-0.47638 1.36106,-0.36296 2.63141,-0.86202 3.81104,-1.4972 1.17958,-0.68053 2.22308,-1.4745 3.1305,-2.3819 0.95272,-0.90738 1.56521,-1.92819 1.83746,-3.06244 l 1.36109,0.40833 c -0.45373,1.36109 -1.17964,2.56338 -2.17774,3.60687 -0.99816,1.04351 -2.15508,1.92821 -3.47077,2.65412 -1.27037,0.68055 -2.63145,1.20229 -4.08325,1.56525 -1.40648,0.36296 -2.74488,0.54443 -4.01521,0.54443 -2.44997,0 -4.71844,-0.52175 -6.80542,-1.56524 -2.08701,-1.0435 -3.90179,-2.42727 -5.44435,-4.15132 -1.4972,-1.72403 -2.6768,-3.67492 -3.53882,-5.85266 -0.81665,-2.17773 -1.22498,-4.40083 -1.22498,-6.66932"
id="path8178-6-8-8-5"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 452.04084,802.31317 -15.04,-20.21212 -9.59565,8.71095 0,11.50117 -1.36109,0 0,-49.67962 1.36109,0 0,36.34098 24.09121,-21.84542 1.83747,0 -15.31221,14.01918 15.65248,21.16488 -1.6333,0"
id="path8180-4-3-9-8"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 508.96505,800.95209 0,1.36108 c -0.77132,-0.0454 -1.3838,-0.31758 -1.83747,-0.81665 -0.40835,-0.54443 -0.61252,-1.17961 -0.61249,-1.90552 l 0,-3.2666 c -1.8148,2.31384 -4.08328,4.0152 -6.80542,5.10407 -2.67683,1.04349 -5.39899,1.56524 -8.16652,1.56524 -1.58794,0 -3.08514,-0.27221 -4.49158,-0.81665 -1.40646,-0.5898 -2.63144,-1.36108 -3.67493,-2.31384 -0.99813,-0.99813 -1.7921,-2.15505 -2.3819,-3.47077 -0.58981,-1.31571 -0.88471,-2.72216 -0.8847,-4.21937 -1e-5,-1.9055 0.47637,-3.49343 1.42914,-4.76379 0.95275,-1.3157 2.13236,-2.3592 3.53882,-3.1305 1.45181,-0.77126 3.01706,-1.3157 4.69574,-1.6333 1.72403,-0.36294 3.35733,-0.54442 4.89991,-0.54444 2.90363,2e-5 5.37626,0.24955 7.41792,0.7486 2.0416,0.45371 3.5161,0.86204 4.42352,1.22498 l 0,-4.01521 c -3e-5,-1.81475 -0.27224,-3.47074 -0.81665,-4.96796 -0.54446,-1.49716 -1.33843,-2.79019 -2.3819,-3.87909 -0.99815,-1.08884 -2.20044,-1.92817 -3.60687,-2.51801 -1.40648,-0.58977 -2.99441,-0.88467 -4.7638,-0.88471 -1.72406,4e-5 -3.56152,0.38568 -5.5124,1.15693 -1.9509,0.72594 -3.92447,1.79212 -5.92072,3.19855 l -0.81665,-1.08887 c 1.86014,-1.27032 3.81103,-2.35918 5.85267,-3.26661 2.08698,-0.90735 4.21934,-1.36105 6.3971,-1.36108 2.13234,3e-5 3.99249,0.36299 5.58045,1.08887 1.63327,0.68057 2.99436,1.63333 4.08325,2.85828 1.08884,1.225 1.90549,2.67683 2.44996,4.35547 0.5444,1.63333 0.81662,3.40274 0.81665,5.30823 l 0,19.53158 c 0.0907,0.40833 0.20413,0.7486 0.34027,1.02081 0.13608,0.22685 0.38561,0.34028 0.7486,0.34028 m -3.47077,-5.58045 c 0.68051,-0.99813 1.02078,-1.9282 1.02081,-2.79023 l 0,-7.00959 c -1.95091,-0.77126 -3.92449,-1.3157 -5.92072,-1.6333 -1.95091,-0.31757 -3.92448,-0.47636 -5.92072,-0.47638 -1.45184,2e-5 -2.94903,0.15881 -4.49158,0.47638 -1.54258,0.27223 -2.97172,0.74861 -4.28742,1.42914 -1.27036,0.68056 -2.33654,1.58795 -3.19855,2.72217 -0.81666,1.08888 -1.22498,2.44996 -1.22498,4.08325 0,1.45184 0.27221,2.76755 0.81665,3.94715 0.5898,1.13425 1.3384,2.10969 2.24579,2.92634 0.95275,0.81665 2.01894,1.45182 3.19855,1.90552 1.22497,0.45369 2.49531,0.68054 3.81104,0.68054 1.27033,0 2.58605,-0.11342 3.94715,-0.34027 1.36107,-0.27222 2.6541,-0.65786 3.8791,-1.15693 1.27032,-0.49906 2.42724,-1.13423 3.47076,-1.90552 1.08884,-0.81664 1.97355,-1.7694 2.65412,-2.85827"
id="path8182-9-5-6-2"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 516.98694,797.41326 1.02082,-0.8847 c 3.67492,3.40271 7.80354,5.10407 12.38587,5.10407 1.36107,0 2.74484,-0.13611 4.15132,-0.40833 1.40643,-0.31758 2.67677,-0.79396 3.81104,-1.42914 1.17958,-0.68054 2.13234,-1.54256 2.85827,-2.58606 0.77126,-1.08886 1.1569,-2.38189 1.15693,-3.87909 -3e-5,-1.63329 -0.40836,-2.97169 -1.22498,-4.01521 -0.77131,-1.04348 -1.76944,-1.83745 -2.99439,-2.38189 -1.225,-0.58979 -2.5634,-0.97543 -4.0152,-1.15693 -1.40647,-0.22683 -2.74487,-0.34025 -4.0152,-0.34027 -1.67869,2e-5 -3.28931,-0.15878 -4.83186,-0.47638 -1.54257,-0.36294 -2.90365,-0.90737 -4.08325,-1.6333 -1.13425,-0.77126 -2.04164,-1.76939 -2.72217,-2.99439 -0.68055,-1.22495 -1.02082,-2.72215 -1.02082,-4.49158 0,-1.72402 0.38564,-3.17584 1.15693,-4.35548 0.77127,-1.17957 1.74671,-2.13233 2.92633,-2.85827 1.22497,-0.77125 2.56337,-1.31569 4.0152,-1.63331 1.49718,-0.36292 2.97169,-0.5444 4.42353,-0.54443 2.99437,3e-5 5.3309,0.45373 7.00959,1.36108 1.67865,0.86206 3.0851,2.10972 4.21936,3.74299 l -1.22497,0.54443 c -0.45372,-0.86199 -1.06621,-1.56521 -1.83747,-2.10968 -0.7713,-0.58977 -1.61064,-1.04347 -2.51801,-1.36108 -0.90741,-0.31756 -1.86017,-0.52172 -2.85828,-0.61249 -0.99814,-0.13608 -1.92822,-0.20413 -2.79022,-0.20417 -1.31573,4e-5 -2.65413,0.15883 -4.0152,0.47638 -1.31573,0.27225 -2.51802,0.72595 -3.60688,1.36109 -1.04351,0.6352 -1.90553,1.47454 -2.58606,2.51801 -0.63518,0.99816 -0.95277,2.22313 -0.95276,3.67493 -10e-6,1.63333 0.34026,2.99441 1.02081,4.08325 0.68054,1.04352 1.56524,1.88286 2.65412,2.51801 1.08886,0.58983 2.29115,1.02084 3.60688,1.29303 1.36107,0.22687 2.69947,0.34029 4.0152,0.34028 1.58791,1e-5 3.19853,0.15881 4.83185,0.47638 1.63328,0.27223 3.0851,0.77129 4.35548,1.49719 1.31568,0.68056 2.38187,1.63332 3.19855,2.85828 0.81662,1.17962 1.22494,2.65413 1.22497,4.42353 -3e-5,1.76942 -0.43104,3.28929 -1.29303,4.55963 -0.81668,1.22498 -1.88286,2.22311 -3.19855,2.99439 -1.31574,0.72591 -2.76756,1.24766 -4.35547,1.56525 -1.54259,0.36296 -3.03978,0.54443 -4.49159,0.54443 -2.94903,0 -5.53509,-0.54443 -7.75818,-1.6333 -2.22312,-1.08886 -4.10595,-2.40458 -5.64851,-3.94715"
id="path8184-5-3-0-1"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 550.74825,797.41326 1.02081,-0.8847 c 3.67493,3.40271 7.80355,5.10407 12.38588,5.10407 1.36107,0 2.74484,-0.13611 4.15131,-0.40833 1.40643,-0.31758 2.67678,-0.79396 3.81104,-1.42914 1.17958,-0.68054 2.13234,-1.54256 2.85828,-2.58606 0.77125,-1.08886 1.1569,-2.38189 1.15692,-3.87909 -2e-5,-1.63329 -0.40835,-2.97169 -1.22497,-4.01521 -0.77131,-1.04348 -1.76944,-1.83745 -2.99439,-2.38189 -1.225,-0.58979 -2.5634,-0.97543 -4.0152,-1.15693 -1.40648,-0.22683 -2.74488,-0.34025 -4.01521,-0.34027 -1.67868,2e-5 -3.2893,-0.15878 -4.83185,-0.47638 -1.54257,-0.36294 -2.90366,-0.90737 -4.08326,-1.6333 -1.13424,-0.77126 -2.04163,-1.76939 -2.72217,-2.99439 -0.68054,-1.22495 -1.02081,-2.72215 -1.02081,-4.49158 0,-1.72402 0.38564,-3.17584 1.15692,-4.35548 0.77128,-1.17957 1.74672,-2.13233 2.92634,-2.85827 1.22496,-0.77125 2.56336,-1.31569 4.0152,-1.63331 1.49718,-0.36292 2.97169,-0.5444 4.42353,-0.54443 2.99436,3e-5 5.33089,0.45373 7.00959,1.36108 1.67864,0.86206 3.0851,2.10972 4.21936,3.74299 l -1.22498,0.54443 c -0.45372,-0.86199 -1.0662,-1.56521 -1.83746,-2.10968 -0.77131,-0.58977 -1.61064,-1.04347 -2.51801,-1.36108 -0.90741,-0.31756 -1.86017,-0.52172 -2.85828,-0.61249 -0.99815,-0.13608 -1.92822,-0.20413 -2.79022,-0.20417 -1.31574,4e-5 -2.65413,0.15883 -4.01521,0.47638 -1.31572,0.27225 -2.51801,0.72595 -3.60687,1.36109 -1.04351,0.6352 -1.90553,1.47454 -2.58607,2.51801 -0.63517,0.99816 -0.95276,2.22313 -0.95276,3.67493 0,1.63333 0.34027,2.99441 1.02082,4.08325 0.68053,1.04352 1.56524,1.88286 2.65412,2.51801 1.08885,0.58983 2.29114,1.02084 3.60687,1.29303 1.36107,0.22687 2.69947,0.34029 4.0152,0.34028 1.58792,1e-5 3.19854,0.15881 4.83186,0.47638 1.63328,0.27223 3.0851,0.77129 4.35547,1.49719 1.31569,0.68056 2.38187,1.63332 3.19855,2.85828 0.81662,1.17962 1.22495,2.65413 1.22498,4.42353 -3e-5,1.76942 -0.43104,3.28929 -1.29303,4.55963 -0.81668,1.22498 -1.88286,2.22311 -3.19855,2.99439 -1.31574,0.72591 -2.76757,1.24766 -4.35548,1.56525 -1.54258,0.36296 -3.03977,0.54443 -4.49158,0.54443 -2.94903,0 -5.53509,-0.54443 -7.75819,-1.6333 -2.22311,-1.08886 -4.10594,-2.40458 -5.6485,-3.94715"
id="path8186-8-1-1-5"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 606.57401,797.41326 1.02081,-0.8847 c 3.67493,3.40271 7.80355,5.10407 12.38588,5.10407 1.36107,0 2.74484,-0.13611 4.15131,-0.40833 1.40643,-0.31758 2.67678,-0.79396 3.81104,-1.42914 1.17958,-0.68054 2.13234,-1.54256 2.85828,-2.58606 0.77125,-1.08886 1.15689,-2.38189 1.15692,-3.87909 -3e-5,-1.63329 -0.40835,-2.97169 -1.22497,-4.01521 -0.77131,-1.04348 -1.76944,-1.83745 -2.99439,-2.38189 -1.225,-0.58979 -2.5634,-0.97543 -4.0152,-1.15693 -1.40648,-0.22683 -2.74488,-0.34025 -4.01521,-0.34027 -1.67868,2e-5 -3.2893,-0.15878 -4.83185,-0.47638 -1.54257,-0.36294 -2.90366,-0.90737 -4.08326,-1.6333 -1.13424,-0.77126 -2.04163,-1.76939 -2.72217,-2.99439 -0.68054,-1.22495 -1.02081,-2.72215 -1.02081,-4.49158 0,-1.72402 0.38564,-3.17584 1.15692,-4.35548 0.77128,-1.17957 1.74672,-2.13233 2.92634,-2.85827 1.22496,-0.77125 2.56336,-1.31569 4.0152,-1.63331 1.49718,-0.36292 2.97169,-0.5444 4.42353,-0.54443 2.99436,3e-5 5.33089,0.45373 7.00959,1.36108 1.67864,0.86206 3.0851,2.10972 4.21936,3.74299 l -1.22498,0.54443 c -0.45372,-0.86199 -1.0662,-1.56521 -1.83746,-2.10968 -0.77131,-0.58977 -1.61064,-1.04347 -2.51801,-1.36108 -0.90741,-0.31756 -1.86017,-0.52172 -2.85828,-0.61249 -0.99815,-0.13608 -1.92822,-0.20413 -2.79022,-0.20417 -1.31574,4e-5 -2.65413,0.15883 -4.01521,0.47638 -1.31572,0.27225 -2.51801,0.72595 -3.60687,1.36109 -1.04351,0.6352 -1.90553,1.47454 -2.58607,2.51801 -0.63517,0.99816 -0.95276,2.22313 -0.95276,3.67493 0,1.63333 0.34027,2.99441 1.02082,4.08325 0.68053,1.04352 1.56524,1.88286 2.65412,2.51801 1.08885,0.58983 2.29114,1.02084 3.60687,1.29303 1.36107,0.22687 2.69947,0.34029 4.0152,0.34028 1.58792,1e-5 3.19854,0.15881 4.83186,0.47638 1.63328,0.27223 3.0851,0.77129 4.35547,1.49719 1.31569,0.68056 2.38187,1.63332 3.19855,2.85828 0.81662,1.17962 1.22495,2.65413 1.22498,4.42353 -3e-5,1.76942 -0.43104,3.28929 -1.29303,4.55963 -0.81668,1.22498 -1.88286,2.22311 -3.19855,2.99439 -1.31574,0.72591 -2.76757,1.24766 -4.35548,1.56525 -1.54258,0.36296 -3.03977,0.54443 -4.49158,0.54443 -2.94903,0 -5.53509,-0.54443 -7.75819,-1.6333 -2.22311,-1.08886 -4.10594,-2.40458 -5.6485,-3.94715"
id="path8188-8-4-7-2"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 657.14471,802.99371 c -2.49534,-0.0454 -4.7865,-0.5898 -6.87348,-1.6333 -2.04164,-1.0435 -3.81105,-2.40458 -5.30824,-4.08326 -1.45183,-1.72403 -2.58607,-3.65223 -3.40271,-5.78461 -0.81666,-2.17772 -1.22498,-4.42351 -1.22498,-6.73737 0,-2.44994 0.43101,-4.78646 1.29303,-7.00959 0.90739,-2.22308 2.10968,-4.17397 3.60688,-5.85267 1.54255,-1.67864 3.33465,-2.99435 5.37629,-3.94715 2.04161,-0.99809 4.21934,-1.49716 6.53321,-1.49719 2.54067,3e-5 4.83183,0.54447 6.87348,1.6333 2.08697,1.0889 3.85638,2.49536 5.30823,4.21937 1.49716,1.72407 2.6314,3.69764 3.40272,5.92072 0.81661,2.17776 1.22494,4.35549 1.22497,6.53321 -3e-5,2.4046 -0.43104,4.69576 -1.29303,6.87348 -0.86205,2.17775 -2.06435,4.10595 -3.60687,5.78461 -1.49723,1.67868 -3.26664,3.01708 -5.30824,4.01521 -2.04165,0.99813 -4.24207,1.51987 -6.60126,1.56524 m -15.44832,-18.23854 c 0.0907,2.17775 0.52174,4.28743 1.29303,6.32905 0.77127,2.04163 1.83745,3.85641 3.19855,5.44434 1.36107,1.54257 2.949,2.79023 4.7638,3.74298 1.86013,0.90739 3.92444,1.36109 6.19294,1.36109 2.31382,0 4.4235,-0.49906 6.32904,-1.4972 1.9055,-0.99812 3.5388,-2.29115 4.89991,-3.87909 1.36105,-1.63329 2.40455,-3.44807 3.1305,-5.44434 0.72588,-2.04162 1.08883,-4.06056 1.08887,-6.05683 -4e-5,-2.17772 -0.40836,-4.2874 -1.22498,-6.32905 -0.77132,-2.0416 -1.86018,-3.8337 -3.2666,-5.37629 -1.36112,-1.5879 -2.99442,-2.85824 -4.89991,-3.81104 -1.86018,-0.95272 -3.87912,-1.4291 -6.05683,-1.42914 -2.31387,4e-5 -4.42355,0.52179 -6.32905,1.56525 -1.90553,0.99816 -3.53883,2.31388 -4.89991,3.94715 -1.36109,1.58796 -2.40459,3.40274 -3.1305,5.44434 -0.72591,1.99628 -1.08887,3.99254 -1.08886,5.98878"
id="path8190-2-0-2-0"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 680.7266,784.75517 c -10e-6,-2.3592 0.38563,-4.62767 1.15692,-6.80543 0.81665,-2.22308 1.95088,-4.17397 3.40271,-5.85267 1.45182,-1.72401 3.17586,-3.08509 5.17213,-4.08325 2.04161,-1.04347 4.26472,-1.56522 6.66932,-1.56525 3.76564,3e-5 6.71466,0.74863 8.84705,2.24579 2.13234,1.45186 3.78833,3.33469 4.96796,5.6485 l -1.29303,0.47638 c -1.31574,-2.44992 -3.06247,-4.21933 -5.24018,-5.30823 -2.17776,-1.1342 -4.60502,-1.70132 -7.2818,-1.70136 -2.4046,4e-5 -4.53697,0.52179 -6.39711,1.56525 -1.86016,0.99816 -3.4254,2.31388 -4.69574,3.94715 -1.27035,1.58796 -2.2458,3.40274 -2.92633,5.44434 -0.68055,1.99628 -1.02082,3.99254 -1.02082,5.98878 0,2.22312 0.40832,4.35549 1.22498,6.3971 0.81664,1.99627 1.9282,3.78836 3.33466,5.37629 1.40644,1.54257 3.06243,2.79023 4.96796,3.74298 1.9055,0.90739 3.94713,1.36109 6.12489,1.36109 1.08884,0 2.29113,-0.15879 3.60687,-0.47638 1.36106,-0.36296 2.63141,-0.86202 3.81104,-1.4972 1.17958,-0.68053 2.22308,-1.4745 3.1305,-2.3819 0.95273,-0.90738 1.56521,-1.92819 1.83746,-3.06244 l 1.36109,0.40833 c -0.45373,1.36109 -1.17964,2.56338 -2.17774,3.60687 -0.99816,1.04351 -2.15508,1.92821 -3.47077,2.65412 -1.27037,0.68055 -2.63145,1.20229 -4.08325,1.56525 -1.40648,0.36296 -2.74488,0.54443 -4.0152,0.54443 -2.44998,0 -4.71845,-0.52175 -6.80543,-1.56524 -2.08701,-1.0435 -3.90179,-2.42727 -5.44434,-4.15132 -1.4972,-1.72403 -2.67681,-3.67492 -3.53883,-5.85266 -0.81665,-2.17773 -1.22498,-4.40083 -1.22497,-6.66932"
id="path8192-6-0-6-5"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 718.96457,802.31317 0,-35.18406 1.36109,0 0,35.18406 -1.36109,0 m 0,-44.43944 0,-4.35547 1.36109,0 0,4.35547 -1.36109,0"
id="path8194-1-1-5-9"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 756.72513,800.95209 0,1.36108 c -0.77131,-0.0454 -1.3838,-0.31758 -1.83746,-0.81665 -0.40836,-0.54443 -0.61252,-1.17961 -0.61249,-1.90552 l 0,-3.2666 c -1.81481,2.31384 -4.08328,4.0152 -6.80543,5.10407 -2.67682,1.04349 -5.39899,1.56524 -8.16651,1.56524 -1.58795,0 -3.08514,-0.27221 -4.49158,-0.81665 -1.40647,-0.5898 -2.63144,-1.36108 -3.67493,-2.31384 -0.99814,-0.99813 -1.7921,-2.15505 -2.3819,-3.47077 -0.58981,-1.31571 -0.88471,-2.72216 -0.88471,-4.21937 0,-1.9055 0.47638,-3.49343 1.42914,-4.76379 0.95275,-1.3157 2.13236,-2.3592 3.53882,-3.1305 1.45182,-0.77126 3.01706,-1.3157 4.69575,-1.6333 1.72403,-0.36294 3.35733,-0.54442 4.89991,-0.54444 2.90362,2e-5 5.37626,0.24955 7.41791,0.7486 2.0416,0.45371 3.51611,0.86204 4.42353,1.22498 l 0,-4.01521 c -3e-5,-1.81475 -0.27225,-3.47074 -0.81665,-4.96796 -0.54446,-1.49716 -1.33843,-2.79019 -2.3819,-3.87909 -0.99816,-1.08884 -2.20045,-1.92817 -3.60688,-2.51801 -1.40647,-0.58977 -2.99441,-0.88467 -4.7638,-0.88471 -1.72406,4e-5 -3.56152,0.38568 -5.51239,1.15693 -1.9509,0.72594 -3.92448,1.79212 -5.92072,3.19855 l -0.81666,-1.08887 c 1.86015,-1.27032 3.81103,-2.35918 5.85267,-3.26661 2.08699,-0.90735 4.21935,-1.36105 6.3971,-1.36108 2.13235,3e-5 3.9925,0.36299 5.58045,1.08887 1.63328,0.68057 2.99437,1.63333 4.08326,2.85828 1.08884,1.225 1.90549,2.67683 2.44995,4.35547 0.54441,1.63333 0.81662,3.40274 0.81666,5.30823 l 0,19.53158 c 0.0907,0.40833 0.20413,0.7486 0.34027,1.02081 0.13607,0.22685 0.38561,0.34028 0.74859,0.34028 m -3.47076,-5.58045 c 0.68051,-0.99813 1.02078,-1.9282 1.02081,-2.79023 l 0,-7.00959 c -1.95092,-0.77126 -3.92449,-1.3157 -5.92072,-1.6333 -1.95091,-0.31757 -3.92449,-0.47636 -5.92072,-0.47638 -1.45185,2e-5 -2.94904,0.15881 -4.49159,0.47638 -1.54257,0.27223 -2.97171,0.74861 -4.28741,1.42914 -1.27036,0.68056 -2.33654,1.58795 -3.19856,2.72217 -0.81665,1.08888 -1.22498,2.44996 -1.22497,4.08325 -1e-5,1.45184 0.27221,2.76755 0.81665,3.94715 0.5898,1.13425 1.33839,2.10969 2.24579,2.92634 0.95275,0.81665 2.01893,1.45182 3.19855,1.90552 1.22496,0.45369 2.49531,0.68054 3.81104,0.68054 1.27033,0 2.58604,-0.11342 3.94715,-0.34027 1.36106,-0.27222 2.65409,-0.65786 3.87909,-1.15693 1.27032,-0.49906 2.42725,-1.13423 3.47077,-1.90552 1.08884,-0.81664 1.97354,-1.7694 2.65412,-2.85827"
id="path8196-3-8-4-4"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 767.12894,797.07299 0,-44.43944 1.36109,0 0,44.43944 c -1e-5,0.99814 0.34026,1.97358 1.02081,2.92634 0.72591,0.90739 1.74672,1.36108 3.06245,1.36108 0.45368,0 0.90737,-0.0227 1.36108,-0.068 0.49905,-0.0907 0.95275,-0.15879 1.36109,-0.20417 0.40831,-0.0907 0.74858,-0.15879 1.02081,-0.20416 0.2722,-0.0907 0.40831,-0.13611 0.40833,-0.13611 l 0.61248,1.29303 c -10e-6,0 -0.1588,0.0454 -0.47637,0.13611 -0.27224,0.0454 -0.63519,0.0907 -1.08887,0.13611 -0.45371,0.0907 -0.97546,0.15879 -1.56525,0.20416 -0.54445,0.0907 -1.11157,0.13611 -1.70136,0.13611 -1.72405,0 -3.06245,-0.54443 -4.0152,-1.6333 -0.9074,-1.13424 -1.36109,-2.44995 -1.36109,-3.94715"
id="path8198-0-2-2-7"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 832.35578,782.64549 0,19.66768 -1.36109,0 0,-19.66768 c -3e-5,-1.86013 -0.0908,-3.67491 -0.27221,-5.44435 -0.18151,-1.76938 -0.58984,-3.35731 -1.22498,-4.7638 -0.6352,-1.40642 -1.56528,-2.51797 -2.79022,-3.33466 -1.17964,-0.86198 -2.81294,-1.29299 -4.89991,-1.29303 -1.8148,4e-5 -3.56153,0.34031 -5.24018,1.02082 -1.67869,0.68057 -3.19857,1.58796 -4.55964,2.72217 -1.36109,1.13427 -2.5407,2.44998 -3.53882,3.94715 -0.99814,1.45185 -1.72405,2.94904 -2.17774,4.49158 l 0,22.3218 -1.36108,0 0,-35.32017 1.36108,0 0,9.11928 c 0.72591,-1.40643 1.65598,-2.69946 2.79023,-3.8791 1.13423,-1.22494 2.38189,-2.24576 3.74298,-3.06244 1.36107,-0.86199 2.8129,-1.51984 4.35548,-1.97357 1.54254,-0.49903 3.0851,-0.74857 4.62769,-0.7486 2.4953,3e-5 4.44618,0.52178 5.85267,1.56525 1.40642,0.99816 2.44992,2.29119 3.13049,3.87909 0.72588,1.54259 1.15689,3.28932 1.29303,5.24018 0.18145,1.90554 0.27219,3.74301 0.27222,5.5124"
id="path8200-9-5-1-6"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 840.49463,784.75517 c 0.0454,-2.3592 0.45369,-4.62767 1.22498,-6.80543 0.81665,-2.22308 1.9282,-4.17397 3.33466,-5.85267 1.45181,-1.72401 3.17585,-3.08509 5.17212,-4.08325 1.99625,-1.04347 4.21935,-1.56522 6.66932,-1.56525 2.58604,3e-5 4.92257,0.4991 7.00959,1.49719 2.13234,0.99816 3.94712,2.33656 5.44435,4.0152 1.49716,1.67871 2.65408,3.62959 3.47076,5.85267 0.86199,2.17776 1.31568,4.46892 1.36109,6.87348 l 0,0.7486 -32.32578,0 c 0.1361,2.13238 0.61248,4.17401 1.42914,6.12489 0.86201,1.95089 1.97356,3.67493 3.33466,5.17212 1.40644,1.4972 3.01706,2.69949 4.83185,3.60688 1.86014,0.86202 3.87908,1.29303 6.05683,1.29303 1.27033,0 2.54067,-0.15879 3.81104,-0.47638 1.31569,-0.36296 2.54067,-0.86202 3.67493,-1.4972 1.13421,-0.63517 2.15502,-1.40645 3.06244,-2.31384 0.90736,-0.90739 1.63327,-1.95088 2.17774,-3.1305 l 1.29303,0.34027 c -0.54447,1.3611 -1.33843,2.58607 -2.3819,3.67493 -0.99816,1.04351 -2.15508,1.92821 -3.47077,2.65412 -1.27037,0.68055 -2.63145,1.20229 -4.08325,1.56525 -1.40648,0.36296 -2.76756,0.54443 -4.08326,0.54443 -2.44997,0 -4.71844,-0.52175 -6.80543,-1.56524 -2.08701,-1.0435 -3.90178,-2.42727 -5.44434,-4.15132 -1.4972,-1.72403 -2.67681,-3.67492 -3.53882,-5.85266 -0.81666,-2.17773 -1.22498,-4.40083 -1.22498,-6.66932 m 32.25773,-0.68054 c -0.13614,-2.31383 -0.63521,-4.44619 -1.4972,-6.39711 -0.81668,-1.99623 -1.90555,-3.72027 -3.2666,-5.17212 -1.36112,-1.45179 -2.99442,-2.58603 -4.89991,-3.40272 -1.86017,-0.86198 -3.92448,-1.29299 -6.19294,-1.29303 -2.31386,4e-5 -4.40086,0.4991 -6.26099,1.4972 -1.81479,0.95279 -3.35735,2.20045 -4.62769,3.74298 -1.27036,1.54259 -2.26848,3.28932 -2.99439,5.24018 -0.68055,1.90554 -1.06619,3.83375 -1.15692,5.78462 l 30.89664,0"
id="path8202-8-8-7-3"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 895.96416,800.67987 c -2e-5,0 -0.18149,0.11342 -0.54443,0.34027 -0.31761,0.22685 -0.7713,0.4537 -1.36109,0.68054 -0.54445,0.22685 -1.2023,0.43101 -1.97357,0.61249 -0.7713,0.22685 -1.63332,0.34027 -2.58606,0.34027 -1.63332,0 -3.06245,-0.49906 -4.28742,-1.49719 -1.22499,-0.99813 -1.83747,-2.31384 -1.83747,-3.94715 l 0,-28.85501 -5.10407,0 0,-1.36109 5.10407,0 0,-12.31782 1.36109,0 0,12.31782 8.50678,0 0,1.36109 -8.50678,0 0,28.85501 c 0.0907,1.31572 0.61248,2.33653 1.56525,3.06244 0.95275,0.68055 2.01893,1.02082 3.19855,1.02082 0.77127,0 1.49718,-0.0907 2.17773,-0.27222 0.68053,-0.18148 1.27033,-0.36295 1.76942,-0.54443 0.54441,-0.22685 0.95274,-0.43101 1.22497,-0.61249 0.31757,-0.18148 0.49905,-0.27222 0.54444,-0.27222 l 0.74859,1.08887"
id="path8204-2-1-5-5"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 947.75772,766.993 1.49719,0 -15.44832,35.32017 -1.22498,0 -8.64289,-19.80379 -8.64289,19.80379 -1.22498,0 -15.44832,-35.32017 1.49719,0 14.56362,33.3466 8.50678,-19.53158 -5.92072,-13.67891 1.42914,0 5.24018,11.9095 5.24018,-11.9095 1.42914,0 -5.92072,13.67891 8.50678,19.53158 14.56362,-33.3466"
id="path8206-0-4-2-4"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 969.90197,802.99371 c -2.49534,-0.0454 -4.7865,-0.5898 -6.87348,-1.6333 -2.04164,-1.0435 -3.81105,-2.40458 -5.30824,-4.08326 -1.45183,-1.72403 -2.58606,-3.65223 -3.40271,-5.78461 -0.81665,-2.17772 -1.22498,-4.42351 -1.22498,-6.73737 0,-2.44994 0.43101,-4.78646 1.29304,-7.00959 0.90738,-2.22308 2.10967,-4.17397 3.60687,-5.85267 1.54256,-1.67864 3.33465,-2.99435 5.37629,-3.94715 2.04161,-0.99809 4.21935,-1.49716 6.53321,-1.49719 2.54067,3e-5 4.83183,0.54447 6.87348,1.6333 2.08697,1.0889 3.85638,2.49536 5.30824,4.21937 1.49716,1.72407 2.63139,3.69764 3.40271,5.92072 0.81661,2.17776 1.22494,4.35549 1.22498,6.53321 -4e-5,2.4046 -0.43105,4.69576 -1.29304,6.87348 -0.86205,2.17775 -2.06434,4.10595 -3.60687,5.78461 -1.49723,1.67868 -3.26664,3.01708 -5.30824,4.01521 -2.04165,0.99813 -4.24207,1.51987 -6.60126,1.56524 m -15.44832,-18.23854 c 0.0907,2.17775 0.52174,4.28743 1.29303,6.32905 0.77128,2.04163 1.83746,3.85641 3.19855,5.44434 1.36108,1.54257 2.94901,2.79023 4.7638,3.74298 1.86013,0.90739 3.92445,1.36109 6.19294,1.36109 2.31382,0 4.4235,-0.49906 6.32905,-1.4972 1.90549,-0.99812 3.53879,-2.29115 4.89991,-3.87909 1.36105,-1.63329 2.40455,-3.44807 3.13049,-5.44434 0.72588,-2.04162 1.08883,-4.06056 1.08887,-6.05683 -4e-5,-2.17772 -0.40836,-4.2874 -1.22498,-6.32905 -0.77131,-2.0416 -1.86018,-3.8337 -3.2666,-5.37629 -1.36112,-1.5879 -2.99442,-2.85824 -4.89991,-3.81104 -1.86017,-0.95272 -3.87912,-1.4291 -6.05683,-1.42914 -2.31386,4e-5 -4.42354,0.52179 -6.32905,1.56525 -1.90553,0.99816 -3.53883,2.31388 -4.89991,3.94715 -1.36109,1.58796 -2.40459,3.40274 -3.13049,5.44434 -0.72592,1.99628 -1.08888,3.99254 -1.08887,5.98878"
id="path8208-6-4-9-0"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 1010.6335,766.993 0,1.36109 c -1.8148,0.0908 -3.4707,0.45373 -4.9679,1.08887 -1.4972,0.58983 -2.8356,1.40648 -4.0152,2.44995 -1.1343,0.99816 -2.10972,2.20045 -2.92636,3.60688 -0.77129,1.36111 -1.38378,2.8583 -1.83747,4.49158 l 0,22.3218 -1.36108,0 0,-35.32017 1.36108,0 0,9.11928 c 1.45182,-2.85826 3.31193,-5.08136 5.58043,-6.66932 2.3139,-1.63327 5.036,-2.44992 8.1665,-2.44996"
id="path8210-6-3-7-7"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 1043.3953,802.31317 -15.04,-20.21212 -9.5957,8.71095 0,11.50117 -1.3611,0 0,-49.67962 1.3611,0 0,36.34098 24.0912,-21.84542 1.8375,0 -15.3122,14.01918 15.6525,21.16488 -1.6333,0"
id="path8212-9-3-7-2"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(-326.13631,-584.40759)"
id="g3895-3-0-6-7"
style="fill:#ffffff">
<path
d="m 688,314.09375 45,110 14,0 45,-110 -12,0 -40,97.78125 -40,-97.78125 z"
id="path3866-2-1-0-6"
style="fill:#ffffff;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0"
transform="translate(-20.00005,308.2677)" />
</g>
<path
d="m 265.36364,37.953855 c -30.31644,0 -55,24.68356 -55,55 0,30.316445 24.68356,55.000005 55,55.000005 30.31644,0 55,-24.68356 55,-55.000005 0,-30.31644 -24.68356,-55 -55,-55 z m 0,10 c 24.91204,0 45,20.08796 45,45 0,24.912045 -20.08796,45.000005 -45,45.000005 -24.91204,0 -45,-20.08796 -45,-45.000005 0,-24.91204 20.08796,-45 45,-45 z"
id="path3905-8-9-2-7"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
inkscape:connector-curvature="0" />
<g
transform="translate(-361.13642,-584.40759)"
id="g3989-3-5-6-8"
style="fill:#ffffff">
<g
transform="translate(-505,0)"
id="g4984-7-6-5-0-0"
style="fill:#ffffff">
<g
transform="translate(499.44444,4.7619024)"
id="g3843-8-0-0-3-1-6"
style="font-size:182.75830078000001322px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Raleway;-inkscape-font-specification:Raleway Bold">
<path
d="m 345,314.09375 0,110 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 429.20859,342.86485 435,355.13541 435,374.09375 l 0,50 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 519.20859,342.86485 525,355.13541 525,374.09375 l 0,50 10,0 0,-50 c 0,-21.04166 -6.7086,-36.2711 -16.46875,-46.03125 C 508.7711,318.30235 496.25003,314.09375 485,314.09375 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -4.13742,4.45568 -7.45035,9.98067 -9.875,16.59375 -2.83134,-6.72178 -6.62945,-12.2857 -11.0625,-16.71875 C 418.7711,318.30235 406.25003,314.09375 395,314.09375 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -1.61794,1.74239 -3.10158,3.65009 -4.46875,5.71875 l 0,-19.8125 z"
id="path3790-8-7-8-7-3-9-1"
style="font-size:182.75830078000001322px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Raleway;-inkscape-font-specification:Raleway Bold"
inkscape:connector-curvature="0"
transform="translate(20.555621,303.5058)" />
</g>
</g>
<g
transform="translate(5,7.3e-4)"
id="g4984-7-7-6-8-5-4"
style="fill:#ffffff">
<g
transform="translate(499.44444,4.7619024)"
id="g3843-8-0-3-7-7-9-0"
style="font-size:182.75830078000001322px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Raleway;-inkscape-font-specification:Raleway Bold">
<path
d="m 345,314.09375 0,110 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 429.20859,342.86485 435,355.13541 435,374.09375 l 0,50 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 519.20859,342.86485 525,355.13541 525,374.09375 l 0,50 10,0 0,-50 c 0,-21.04166 -6.7086,-36.2711 -16.46875,-46.03125 C 508.7711,318.30235 496.25003,314.09375 485,314.09375 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -4.13742,4.45568 -7.45035,9.98067 -9.875,16.59375 -2.83134,-6.72178 -6.62945,-12.2857 -11.0625,-16.71875 C 418.7711,318.30235 406.25003,314.09375 395,314.09375 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -1.61794,1.74239 -3.10158,3.65009 -4.46875,5.71875 l 0,-19.8125 z"
id="path3790-8-7-8-9-2-7-2-6"
style="font-size:182.75830078000001322px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Raleway;-inkscape-font-specification:Raleway Bold"
inkscape:connector-curvature="0"
transform="translate(20.555621,303.5058)" />
</g>
</g>
</g>
</g>
</svg>

238
app/widgets/Login/img/logo2.svg

@ -0,0 +1,238 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="logo2.svg"
inkscape:version="0.48.3.1 r9886"
version="1.1"
id="svg3147"
height="221.5"
width="700">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.15"
inkscape:cx="247.36376"
inkscape:cy="28.277193"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="736"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
fit-margin-top="1"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="1" />
<defs
id="defs3149" />
<metadata
id="metadata3152">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(467,-253.8622)">
<g
transform="translate(-466,255)"
id="layer2"
style="fill:#ffffff">
<g
transform="translate(-346,-584)"
id="g4007-8"
style="fill:#ffffff">
<path
d="m 816,622.3622 0,110 10,0 0,-110 -10,0 z"
id="path3788-7"
style="font-size:182.75830078px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Raleway;-inkscape-font-specification:Raleway Bold"
inkscape:connector-curvature="0" />
<path
d="m 825.33333,289.5748 a 5,5 0 1 1 -10,0 5,5 0 1 1 10,0 z"
transform="matrix(1.5,0,0,1.5,-409,157)"
id="path3850-4"
style="fill:#ffffff;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(-346,-584)"
id="text4011-1"
style="font-size:68.05427551px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Raleway;-inkscape-font-specification:Raleway Light">
<path
d="M 371,803.3622 356.10345,783.01974 346,791.78686 l 0,11.57534 -1,0 0,-50 1,0 0,36.57534 24.7931,-21.57534 1.86207,0 -15.51724,13.69863 L 373,803.3622 l -2,0"
id="path8174-0"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 378,803.3622 0,-35 1,0 0,35 -1,0 m 0,-44.62622 0,-4.37378 1,0 0,5 -1,0"
id="path8176-2"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 387,785.3622 c 0,-2.85411 0.38864,-5.15081 1.16594,-7.35568 0.82299,-2.25075 1.96606,-4.22592 3.4292,-5.92551 1.46312,-1.74547 3.20058,-3.12349 5.21239,-4.13407 2.0575,-1.05646 4.29791,-1.5847 6.72124,-1.58474 3.79495,4e-5 6.76693,0.75795 8.91592,2.27375 2.14894,1.46993 3.81781,3.37619 5.00663,5.7188 l -1.30309,0.48231 c -1.32599,-2.48041 -3.08631,-4.27185 -5.28098,-5.3743 -2.19471,-1.14832 -4.64088,-1.72249 -7.33848,-1.72253 -2.42333,4e-5 -4.57229,0.52828 -6.44691,1.58473 -1.87464,1.01058 -3.45207,2.34268 -4.7323,3.99628 -1.28025,1.60772 -2.26328,3.44509 -2.94912,5.5121 -0.68584,2.02113 -1.02875,4.04223 -1.02875,6.06332 0,2.25079 0.41149,4.4097 1.23451,6.47672 0.823,2.02112 1.9432,3.83551 3.36062,5.44321 1.41739,1.56177 3.08627,2.82495 5.00663,3.78956 1.92034,0.91869 3.97786,1.37803 6.17256,1.37803 1.09733,0 2.30898,-0.16076 3.63496,-0.48231 1.37166,-0.36747 2.6519,-0.87274 3.84071,-1.51583 1.18876,-0.689 2.24039,-1.49285 3.15487,-2.41155 0.96014,-0.91867 1.5774,-1.95219 1.85176,-3.10055 L 418,794.88735 c -0.45726,1.37803 -1.18882,2.59528 -2.19469,3.65176 -1.00593,1.0565 -2.17186,1.95221 -3.49779,2.68716 -1.28026,0.68902 -2.65194,1.21725 -4.11504,1.58473 -1.41743,0.36748 -2.76625,0.5512 -4.04647,0.5512 -2.46904,0 -4.75517,-0.52824 -6.85839,-1.58472 -2.10326,-1.05649 -3.93217,-2.45748 -5.48674,-4.20299 -1.50885,-1.74548 -2.69763,-3.72066 -3.56636,-5.9255 C 387.41151,789.9097 387,787.65893 387,785.3622"
id="path8178-6"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="M 452,803.3622 437.10345,783.01974 427,791.78686 l 0,11.57534 -1,0 0,-50 1,0 0,36.57534 24.7931,-21.57534 1.86207,0 -15.51723,13.69863 L 454,803.3622 l -2,0"
id="path8180-4"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 509,801.29517 0,1.37802 c -0.7752,-0.046 -1.39075,-0.32153 -1.8467,-0.82681 0.0519,-0.55121 -0.15333,-1.19429 -0.1533,-1.92924 l 0,-3.30726 c -2.28619,2.34264 -4.56607,4.06518 -7.30189,5.1676 -2.69028,1.05648 -5.42611,1.58472 -8.20755,1.58472 -1.59592,0 -3.10064,-0.27559 -4.51415,-0.82681 -1.41353,-0.59714 -2.64466,-1.37802 -3.6934,-2.34264 -1.00314,-1.01055 -1.8011,-2.18187 -2.39386,-3.51397 -0.59278,-1.33208 -0.88916,-2.75604 -0.88915,-4.27188 -10e-6,-1.92922 0.47876,-3.53692 1.43632,-4.82309 0.95754,-1.33207 2.14308,-2.38856 3.5566,-3.16946 1.45911,-0.78086 3.03222,-1.33208 4.71934,-1.65363 1.73269,-0.36746 3.3742,-0.5512 4.92453,-0.55122 2.91822,2e-5 5.40327,0.25266 7.45519,0.75792 2.51413,0.45936 3.99604,0.87277 4.90802,1.24023 l 0,-4.06519 c -0.4623,-1.83733 -0.73588,-3.51394 -1.28302,-5.02979 -0.5472,-1.5158 -1.34516,-2.82492 -2.39387,-3.92737 -1.00317,-1.10239 -2.2115,-1.95217 -3.625,-2.54935 -1.41354,-0.59711 -3.00945,-0.89568 -4.78773,-0.89572 -1.73273,4e-5 -3.57942,0.39048 -5.5401,1.17133 -1.9607,0.73497 -3.94419,1.81442 -5.95047,3.23836 l -0.82076,-1.10243 c 1.86949,-1.28613 3.83018,-2.38854 5.88208,-3.30726 2.09747,-0.91865 4.24054,-1.37799 6.42925,-1.37803 2.14305,4e-5 4.01255,0.36751 5.60849,1.10243 1.64147,0.68904 3.0094,1.65366 4.10376,2.89385 1.09432,1.24025 1.91507,2.71015 2.46228,4.40968 0.64147,1.65366 0.91506,3.4451 0.91509,5.3743 l 0,19.77468 c -0.003,0.41342 0.11081,0.75792 0.24764,1.03352 0.13676,0.22967 0.38755,0.34451 0.75236,0.34451 m -3.48821,-5.6499 c 1.1462,-1.01056 1.48818,-1.9522 1.48821,-2.82496 l 0,-7.09684 c -2.42298,-0.78086 -4.40648,-1.33207 -6.41274,-1.65363 -1.96071,-0.32152 -3.9442,-0.48229 -5.95047,-0.48231 -1.45914,2e-5 -2.96385,0.16079 -4.51415,0.48231 -1.55033,0.27562 -2.98665,0.75793 -4.30896,1.44693 -1.27675,0.68903 -2.34828,1.60772 -3.21463,2.75605 -0.82076,1.10244 -1.23113,2.48046 -1.23113,4.13408 0,1.46991 0.27358,2.80199 0.82075,3.99627 0.59277,1.14837 1.34513,2.13595 2.25708,2.96277 0.95753,0.82681 2.02908,1.46989 3.21462,1.92923 1.23112,0.45934 2.50785,0.68901 3.83019,0.68901 1.27671,0 2.59904,-0.11483 3.96698,-0.3445 1.36791,-0.27561 2.66744,-0.66605 3.89859,-1.17133 1.27671,-0.50527 2.43944,-1.14835 3.4882,-1.92924 1.09431,-0.8268 1.98347,-1.79142 2.66746,-2.89384"
id="path8182-9"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 517,798.3622 1.03054,-1.54561 c 3.70991,3.44506 7.87785,5.16759 12.50381,5.16759 1.37403,0 2.77098,-0.1378 4.19085,-0.41341 1.41982,-0.32153 2.70226,-0.80384 3.84733,-1.44693 1.19081,-0.68901 2.15264,-1.56176 2.88548,-2.61824 0.77861,-1.10242 1.16792,-2.41154 1.16795,-3.92737 -3e-5,-1.65362 -0.41225,-3.00868 -1.23664,-4.06519 -0.77866,-1.05647 -1.78629,-1.86032 -3.02291,-2.41154 -1.23666,-0.59713 -2.58781,-0.98757 -4.05343,-1.17133 -1.41986,-0.22965 -2.77101,-0.34448 -4.05343,-0.3445 -1.69468,2e-5 -3.32063,-0.16076 -4.87787,-0.48231 -1.55726,-0.36746 -2.9313,-0.91866 -4.12213,-1.65363 -1.14505,-0.78086 -2.06108,-1.79141 -2.74809,-3.03166 -0.68703,-1.2402 -1.03054,-2.75603 -1.03054,-4.54748 0,-1.74548 0.38931,-3.21537 1.16794,-4.40969 0.77862,-1.19426 1.76334,-2.15887 2.9542,-2.89385 1.23663,-0.78085 2.58778,-1.33207 4.05343,-1.65364 1.51144,-0.36744 2.99999,-0.55117 4.46565,-0.55121 3.02288,4e-5 5.38166,0.45938 7.07634,1.37803 1.69463,0.87279 3.11447,2.13597 4.25953,3.78957 l -1.23663,0.55121 c -0.45804,-0.87272 -1.07636,-1.58469 -1.85497,-2.13594 -0.77864,-0.59711 -1.62597,-1.05646 -2.54198,-1.37802 -0.91605,-0.32151 -1.87789,-0.52821 -2.8855,-0.62011 -1.00764,-0.13778 -1.94658,-0.20667 -2.81679,-0.20671 -1.32826,4e-5 -2.6794,0.1608 -4.05343,0.4823 -1.32826,0.27564 -2.542,0.73499 -3.64123,1.37804 -1.05344,0.6431 -1.92367,1.49289 -2.61068,2.54935 -0.64123,1.01058 -0.96184,2.2508 -0.96183,3.72067 -10e-6,1.65366 0.3435,3.03168 1.03053,4.13407 0.68702,1.05651 1.58014,1.90629 2.67939,2.54935 1.09923,0.59717 2.31297,1.03354 3.64122,1.30912 1.37403,0.2297 2.72518,0.34453 4.05344,0.34452 1.60303,1e-5 3.22898,0.16078 4.87786,0.48231 1.64883,0.27562 3.11447,0.78089 4.39695,1.51582 1.32821,0.68903 2.40455,1.65365 3.22901,2.89386 0.82439,1.1943 1.2366,2.68716 1.23663,4.47859 -3e-5,1.79144 -0.43514,3.33023 -1.30534,4.61638 -0.82446,1.24022 -1.90079,2.25078 -3.22901,3.03166 -1.32827,0.73494 -2.79391,1.26319 -4.39694,1.58473 -1.55728,0.36748 -3.06873,0.5512 -4.53436,0.5512 -2.97711,0 -5.5878,-0.5512 -7.83205,-1.65362 -2.24429,-0.45251 -4.14505,-1.78461 -5.7023,-3.34638"
id="path8184-5"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 551,798.3622 1.03053,-1.54561 c 3.70992,3.44506 7.87786,5.16759 12.50382,5.16759 1.37403,0 2.77098,-0.1378 4.19084,-0.41341 1.41982,-0.32153 2.70227,-0.80384 3.84733,-1.44693 1.19081,-0.68901 2.15264,-1.56176 2.88549,-2.61824 0.7786,-1.10242 1.16792,-2.41154 1.16794,-3.92737 -2e-5,-1.65362 -0.41224,-3.00868 -1.23663,-4.06519 -0.77866,-1.05647 -1.78629,-1.86032 -3.02291,-2.41154 -1.23666,-0.59713 -2.58781,-0.98757 -4.05343,-1.17133 -1.41987,-0.22965 -2.77102,-0.34448 -4.05344,-0.3445 -1.69467,2e-5 -3.32062,-0.16076 -4.87786,-0.48231 -1.55726,-0.36746 -2.93131,-0.91866 -4.12214,-1.65363 -1.14504,-0.78086 -2.06107,-1.79141 -2.74809,-3.03166 -0.68702,-1.2402 -1.03053,-2.75603 -1.03053,-4.54748 0,-1.74548 0.38931,-3.21537 1.16793,-4.40969 0.77863,-1.19426 1.76335,-2.15887 2.95421,-2.89385 1.23662,-0.78085 2.58777,-1.33207 4.05343,-1.65364 1.51144,-0.36744 2.99999,-0.55117 4.46565,-0.55121 3.02287,4e-5 5.38165,0.45938 7.07634,1.37803 1.69462,0.87279 3.11447,2.13597 4.25953,3.78957 l -1.23664,0.55121 c -0.45804,-0.87272 -1.07635,-1.58469 -1.85496,-2.13594 -0.77865,-0.59711 -1.62597,-1.05646 -2.54198,-1.37802 -0.91605,-0.32151 -1.87789,-0.52821 -2.8855,-0.62011 -1.00765,-0.13778 -1.94658,-0.20667 -2.81679,-0.20671 -1.32827,4e-5 -2.6794,0.1608 -4.05344,0.4823 -1.32825,0.27564 -2.54199,0.73499 -3.64122,1.37804 -1.05344,0.6431 -1.92367,1.49289 -2.61069,2.54935 -0.64122,1.01058 -0.96183,2.2508 -0.96183,3.72067 0,1.65366 0.34351,3.03168 1.03054,4.13407 0.68701,1.05651 1.58014,1.90629 2.67939,2.54935 1.09922,0.59717 2.31296,1.03354 3.64121,1.30912 1.37403,0.2297 2.72518,0.34453 4.05344,0.34452 1.60304,1e-5 3.22899,0.16078 4.87787,0.48231 1.64883,0.27562 3.11447,0.78089 4.39694,1.51582 1.32822,0.68903 2.40455,1.65365 3.22901,2.89386 0.82439,1.1943 1.23661,2.68716 1.23664,4.47859 -3e-5,1.79144 -0.43514,3.33023 -1.30534,4.61638 -0.82446,1.24022 -1.90079,2.25078 -3.22901,3.03166 -1.32827,0.73494 -2.79392,1.26319 -4.39695,1.58473 -1.55727,0.36748 -3.06872,0.5512 -4.53435,0.5512 -2.97711,0 -5.5878,-0.5512 -7.83206,-1.65362 -2.24428,-0.45251 -4.14504,-1.78461 -5.70229,-3.34638"
id="path8186-8"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 607,798.3622 1.03053,-1.54561 c 3.70992,3.44506 7.87786,5.16759 12.50382,5.16759 1.37403,0 2.77098,-0.1378 4.19084,-0.41341 1.41982,-0.32153 2.70227,-0.80384 3.84733,-1.44693 1.19081,-0.68901 2.15264,-1.56176 2.88549,-2.61824 0.7786,-1.10242 1.16791,-2.41154 1.16794,-3.92737 -3e-5,-1.65362 -0.41224,-3.00868 -1.23663,-4.06519 -0.77866,-1.05647 -1.78629,-1.86032 -3.02291,-2.41154 -1.23666,-0.59713 -2.58781,-0.98757 -4.05343,-1.17133 -1.41987,-0.22965 -2.77102,-0.34448 -4.05344,-0.3445 -1.69467,2e-5 -3.32062,-0.16076 -4.87786,-0.48231 -1.55726,-0.36746 -2.93131,-0.91866 -4.12214,-1.65363 -1.14504,-0.78086 -2.06107,-1.79141 -2.74809,-3.03166 -0.68702,-1.2402 -1.03053,-2.75603 -1.03053,-4.54748 0,-1.74548 0.38931,-3.21537 1.16793,-4.40969 0.77863,-1.19426 1.76335,-2.15887 2.95421,-2.89385 1.23662,-0.78085 2.58777,-1.33207 4.05343,-1.65364 1.51144,-0.36744 2.99999,-0.55117 4.46565,-0.55121 3.02287,4e-5 5.38165,0.45938 7.07634,1.37803 1.69462,0.87279 3.11447,2.13597 4.25953,3.78957 l -1.23664,0.55121 c -0.45804,-0.87272 -1.07635,-1.58469 -1.85496,-2.13594 -0.77865,-0.59711 -1.62597,-1.05646 -2.54198,-1.37802 -0.91605,-0.32151 -1.87789,-0.52821 -2.8855,-0.62011 -1.00765,-0.13778 -1.94658,-0.20667 -2.81679,-0.20671 -1.32827,4e-5 -2.6794,0.1608 -4.05344,0.4823 -1.32825,0.27564 -2.54199,0.73499 -3.64122,1.37804 -1.05344,0.6431 -1.92367,1.49289 -2.61069,2.54935 -0.64122,1.01058 -0.96183,2.2508 -0.96183,3.72067 0,1.65366 0.34351,3.03168 1.03054,4.13407 0.68701,1.05651 1.58014,1.90629 2.67939,2.54935 1.09922,0.59717 2.31296,1.03354 3.64121,1.30912 1.37403,0.2297 2.72518,0.34453 4.05344,0.34452 1.60304,1e-5 3.22899,0.16078 4.87787,0.48231 1.64883,0.27562 3.11447,0.78089 4.39694,1.51582 1.32822,0.68903 2.40455,1.65365 3.22901,2.89386 0.82439,1.1943 1.23661,2.68716 1.23664,4.47859 -3e-5,1.79144 -0.43514,3.33023 -1.30534,4.61638 -0.82446,1.24022 -1.90079,2.25078 -3.22901,3.03166 -1.32827,0.73494 -2.79392,1.26319 -4.39695,1.58473 -1.55727,0.36748 -3.06872,0.5512 -4.53435,0.5512 -2.97711,0 -5.5878,-0.5512 -7.83206,-1.65362 -2.24428,-0.45251 -4.14504,-1.78461 -5.70229,-3.34638"
id="path8188-8"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 657.00001,803.3622 c -2.52364,-0.046 -4.84078,-0.59714 -6.95142,-1.65362 -2.06479,-1.05649 -3.85426,-2.43451 -5.36843,-4.13409 -1.46829,-1.74548 -2.61539,-3.69768 -3.44129,-5.8566 C 640.41295,789.51306 640,787.23932 640,784.89666 c 0,-2.48043 0.4359,-4.84604 1.30769,-7.09684 0.91768,-2.25075 2.1336,-4.22592 3.64778,-5.92551 1.56004,-1.69954 3.37246,-3.03162 5.43725,-3.99628 2.06476,-1.01051 4.26718,-1.51579 6.60729,-1.51583 2.56947,4e-5 4.88661,0.55125 6.95141,1.65363 2.11063,1.10246 3.90011,2.52642 5.36842,4.27189 1.51413,1.74553 2.66123,3.74366 3.4413,5.99441 0.82587,2.20487 1.23883,4.4097 1.23886,6.61453 -3e-5,2.43453 -0.43593,4.7542 -1.30769,6.95903 -0.87183,2.20485 -2.08776,4.15705 -3.64777,5.85661 -1.5142,1.69957 -3.30368,3.05463 -5.36843,4.06518 -2.0648,1.01056 -4.29017,1.53879 -6.6761,1.58472 m -15.62349,-18.46554 c 0.0917,2.20485 0.52766,4.34079 1.30769,6.40782 0.78002,2.06704 1.85829,3.90441 3.23482,5.51211 1.3765,1.56177 2.98244,2.82495 4.81782,3.78956 1.88122,0.91869 3.96893,1.37803 6.26316,1.37803 2.34005,0 4.47365,-0.50527 6.4008,-1.51583 1.9271,-1.01054 3.57892,-2.31967 4.95547,-3.92737 1.37648,-1.65362 2.43181,-3.49099 3.16599,-5.51211 0.73411,-2.06703 1.10118,-4.1111 1.10122,-6.13221 -4e-5,-2.20483 -0.41299,-4.34076 -1.23887,-6.40783 -0.78007,-2.06701 -1.88127,-3.88141 -3.30364,-5.4432 -1.37655,-1.60767 -3.02837,-2.89382 -4.95547,-3.85848 -1.88127,-0.96457 -3.9231,-1.44688 -6.1255,-1.44692 -2.34011,4e-5 -4.47371,0.52828 -6.40082,1.58473 -1.92713,1.01058 -3.57895,2.34268 -4.95547,3.99628 -1.37652,1.60772 -2.43185,3.44509 -3.16599,5.5121 -0.73414,2.02113 -1.10122,4.04223 -1.10121,6.06332"
id="path8190-2"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 681,785.3622 c -10e-6,-2.85411 0.38863,-5.15081 1.16593,-7.35568 0.823,-2.25075 1.96606,-4.22592 3.4292,-5.92551 1.46312,-1.74547 3.20058,-3.12349 5.21239,-4.13407 2.05751,-1.05646 4.29792,-1.5847 6.72124,-1.58474 3.79496,4e-5 6.76694,0.75795 8.91593,2.27375 2.14894,1.46993 3.81782,3.37619 5.00663,5.7188 l -1.30309,0.48231 c -1.32599,-2.48041 -3.08632,-4.27185 -5.28098,-5.3743 -2.19471,-1.14832 -4.64087,-1.72249 -7.33849,-1.72253 -2.42332,4e-5 -4.57229,0.52828 -6.44691,1.58473 -1.87464,1.01058 -3.45207,2.34268 -4.7323,3.99628 -1.28024,1.60772 -2.26328,3.44509 -2.94911,5.5121 -0.68585,2.02113 -1.02876,4.04223 -1.02876,6.06332 0,2.25079 0.41149,4.4097 1.23451,6.47672 0.823,2.02112 1.94321,3.83551 3.36062,5.44321 1.41739,1.56177 3.08627,2.82495 5.00664,3.78956 1.92033,0.91869 3.97786,1.37803 6.17257,1.37803 1.09732,0 2.30897,-0.16076 3.63495,-0.48231 1.37166,-0.36747 2.6519,-0.87274 3.84071,-1.51583 1.18876,-0.689 2.24039,-1.49285 3.15487,-2.41155 0.96015,-0.91867 1.57739,-1.95219 1.85176,-3.10055 L 712,794.88735 c -0.45726,1.37803 -1.18882,2.59528 -2.19469,3.65176 -1.00593,1.0565 -2.17186,1.95221 -3.49779,2.68716 -1.28026,0.68902 -2.65194,1.21725 -4.11504,1.58473 -1.41743,0.36748 -2.76625,0.5512 -4.04646,0.5512 -2.46905,0 -4.75518,-0.52824 -6.85841,-1.58472 -2.10326,-1.05649 -3.93217,-2.45748 -5.48672,-4.20299 -1.50886,-1.74548 -2.69765,-3.72066 -3.56638,-5.9255 C 681.4115,789.9097 680.99999,787.65893 681,785.3622"
id="path8192-6"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 719,803.3622 0,-35 1,0 0,35 -1,0 m 0,-44.62622 0,-4.37378 1,0 0,5 -1,0"
id="path8194-1"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 757,801.29517 0,1.37802 c -0.77519,-0.046 -1.39075,-0.32153 -1.84669,-0.82681 0.0518,-0.55121 -0.15334,-1.19429 -0.15331,-1.92924 l 0,-3.30726 c -2.28619,2.34264 -4.56606,4.06518 -7.30189,5.1676 -2.69027,1.05648 -5.42611,1.58472 -8.20754,1.58472 -1.59593,0 -3.10064,-0.27559 -4.51415,-0.82681 -1.41354,-0.59714 -2.64466,-1.37802 -3.6934,-2.34264 -1.00315,-1.01055 -1.8011,-2.18187 -2.39386,-3.51397 C 728.29638,795.3467 728,793.92274 728,792.4069 c 0,-1.92922 0.47877,-3.53692 1.43632,-4.82309 0.95754,-1.33207 2.14308,-2.38856 3.5566,-3.16946 1.45912,-0.78086 3.03222,-1.33208 4.71935,-1.65363 1.73269,-0.36746 3.3742,-0.5512 4.92453,-0.55122 2.91821,2e-5 5.40327,0.25266 7.45518,0.75792 2.51412,0.45936 3.99604,0.87277 4.90802,1.24023 l 0,-4.06519 c -0.46229,-1.83733 -0.73588,-3.51394 -1.28301,-5.02979 -0.5472,-1.5158 -1.34516,-2.82492 -2.39387,-3.92737 -1.00318,-1.10239 -2.21151,-1.95217 -3.62501,-2.54935 -1.41353,-0.59711 -3.00945,-0.89568 -4.78773,-0.89572 -1.73273,4e-5 -3.57942,0.39048 -5.54009,1.17133 -1.9607,0.73497 -3.9442,1.81442 -5.95047,3.23836 l -0.82077,-1.10243 c 1.8695,-1.28613 3.83018,-2.38854 5.88208,-3.30726 2.09748,-0.91865 4.24055,-1.37799 6.42925,-1.37803 2.14306,4e-5 4.01256,0.36751 5.60849,1.10243 1.64148,0.68904 3.00941,1.65366 4.10377,2.89385 1.09432,1.24025 1.91507,2.71015 2.46227,4.40968 0.64147,1.65366 0.91505,3.4451 0.91509,5.3743 l 0,19.77468 c -0.003,0.41342 0.11082,0.75792 0.24765,1.03352 0.13675,0.22967 0.38755,0.34451 0.75235,0.34451 m -3.4882,-5.6499 c 1.14619,-1.01056 1.48817,-1.9522 1.4882,-2.82496 l 0,-7.09684 c -2.42298,-0.78086 -4.40647,-1.33207 -6.41273,-1.65363 -1.96071,-0.32152 -3.94421,-0.48229 -5.95047,-0.48231 -1.45915,2e-5 -2.96386,0.16079 -4.51416,0.48231 -1.55032,0.27562 -2.98664,0.75793 -4.30895,1.44693 -1.27675,0.68903 -2.34828,1.60772 -3.21464,2.75605 -0.82075,1.10244 -1.23113,2.48046 -1.23112,4.13408 -10e-6,1.46991 0.27358,2.80199 0.82075,3.99627 0.59277,1.14837 1.34512,2.13595 2.25708,2.96277 0.95753,0.82681 2.02907,1.46989 3.21462,1.92923 1.23111,0.45934 2.50785,0.68901 3.83019,0.68901 1.27671,0 2.59903,-0.11483 3.96698,-0.3445 1.3679,-0.27561 2.66743,-0.66605 3.89858,-1.17133 1.27671,-0.50527 2.43945,-1.14835 3.48821,-1.92924 1.09432,-0.8268 1.98346,-1.79142 2.66746,-2.89384"
id="path8196-3"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 767,797.78393 0,-44.42173 1,0 0,44.42173 c 0.33333,0.99774 0.66666,1.97279 1.33333,2.92517 0.71111,0.90703 1.71111,1.36054 3.00001,1.36054 0.44443,0 0.88887,-0.0227 1.33333,-0.068 0.48887,-0.0907 0.93332,-0.15873 1.33334,-0.20409 0.39998,-0.0907 0.73331,-0.15873 0.99999,-0.20408 0.26665,-0.0907 0.39999,-0.13606 0.40001,-0.13606 L 777,802.74996 c -10e-6,0 -0.15556,0.0454 -0.46666,0.13605 -0.26669,0.0454 -0.62224,0.0907 -1.06667,0.13606 -0.44445,0.0907 -0.95557,0.15873 -1.53333,0.20408 -0.53335,0.0907 -1.08891,0.13605 -1.66667,0.13605 -1.6889,0 -3.00001,-0.54421 -3.93333,-1.63264 C 767.44444,800.59577 767,799.28058 767,797.78398"
id="path8198-0"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 832,783.3622 0,19 -1,0 0,-19.74193 c -0.33998,-1.86715 -0.42934,-3.68878 -0.60794,-5.4649 -0.17869,-1.77606 -0.58068,-3.36999 -1.20596,-4.78179 -0.62533,-1.41173 -1.54097,-2.52747 -2.74689,-3.34725 -1.16132,-0.86523 -2.76926,-1.29787 -4.82382,-1.29791 -1.78662,4e-5 -3.50623,0.3416 -5.15881,1.02468 -1.65263,0.68314 -3.14891,1.59395 -4.48884,2.73244 -1.33996,1.13856 -2.50125,2.45923 -3.48387,3.96206 -1.32259,1.45733 -2.03722,2.96017 -2.48387,4.50853 l 0,22.40607 -1,0 0,-35 1,0 0,8.7002 c 1.05458,-1.41174 1.97021,-2.70965 3.08685,-3.89375 1.11662,-1.22956 2.3449,-2.25424 3.68486,-3.074 1.33993,-0.86524 2.76922,-1.52558 4.28785,-1.98102 1.51858,-0.50091 3.03719,-0.7514 4.55583,-0.75143 2.45655,3e-5 4.37714,0.52375 5.76179,1.57116 1.38458,1.00193 2.41187,2.29984 3.08188,3.89374 0.7146,1.54841 1.13892,3.30174 1.27295,5.25996 0.17863,2.65467 0.26796,4.49907 0.26799,6.27514"
id="path8200-9"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 840,784.89666 c 0.0458,-2.38857 0.45791,-4.68527 1.23637,-6.89014 0.82424,-2.25075 1.94612,-4.22592 3.36565,-5.92551 1.46531,-1.74547 3.20537,-3.12349 5.2202,-4.13407 2.01481,-1.05646 4.25857,-1.5847 6.73131,-1.58474 2.61008,4e-5 4.96833,0.50532 7.07475,1.51583 2.15216,1.01058 3.98381,2.36564 5.49496,4.06517 1.51107,1.69961 2.67875,3.67477 3.50302,5.92552 0.87,2.20487 1.32791,4.52454 1.37374,6.95903 l 0,1.53445 -32.62626,0 c 0.13737,1.38239 0.61817,3.44943 1.44243,5.42459 0.87002,1.97517 1.9919,3.72067 3.36565,5.2365 1.41952,1.51583 3.04511,2.73309 4.87677,3.65177 1.87743,0.87275 3.91513,1.30912 6.11313,1.30912 1.28213,0 2.56428,-0.16076 3.84646,-0.48231 1.32792,-0.36747 2.56429,-0.87274 3.70909,-1.51583 1.14475,-0.64308 2.17505,-1.42396 3.09091,-2.34264 0.91579,-0.91868 1.64845,-1.97516 2.19798,-3.16946 l 1.30505,0.3445 c -0.54953,1.37804 -1.35087,2.61826 -2.40404,3.72067 -1.00744,1.0565 -2.17511,1.95221 -3.50303,2.68716 -1.28218,0.68902 -2.65591,1.21725 -4.12121,1.58473 -1.41955,0.36748 -2.79328,0.5512 -4.12121,0.5512 -2.47275,0 -4.7623,-0.52824 -6.86869,-1.58472 -2.10641,-1.05649 -3.93805,-2.45748 -5.49495,-4.20299 -1.51112,-1.74548 -2.70169,-3.72066 -3.57171,-5.9255 C 840.41212,789.44415 840,787.19338 840,784.89666 m 32.55758,-0.68901 c -0.13741,-2.34263 -0.64112,-4.50153 -1.51112,-6.47673 -0.82427,-2.02108 -1.92326,-3.76658 -3.29697,-5.2365 -1.37377,-1.46986 -3.02225,-2.61822 -4.94545,-3.44507 -1.87746,-0.87271 -3.96096,-1.30908 -6.25051,-1.30912 -2.33536,4e-5 -4.44176,0.50531 -6.31918,1.51583 -1.83166,0.96465 -3.38856,2.22784 -4.67071,3.78957 -1.28217,1.56179 -2.28957,3.33026 -3.02222,5.3054 -0.68688,2.08381 -1.0761,4.03602 -1.16768,6.01117 l 31.18384,0"
id="path8202-8"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 896,801.3622 c -2e-5,0.0255 -0.18463,0.13901 -0.55384,0.36596 -0.3231,0.22696 -0.78464,0.45391 -1.38462,0.68085 -0.55386,0.22696 -1.22309,0.43121 -2.00769,0.61277 -0.78463,0.22695 -1.66156,0.34042 -2.63077,0.34042 -1.66155,0 -3.11539,-0.49928 -4.36154,-1.49786 C 883.62307,800.86575 883,799.54945 883,797.9154 l 0,-28.5532 -5,0 0,-1 5,0 0,-13 2,0 0,13 8,0 0,1 -8,0 0,28.5532 c -0.3308,1.31631 0.2,2.33759 1.16924,3.06383 0.96922,0.68085 2.05383,1.02128 3.25384,1.02128 0.78461,0 1.52307,-0.0907 2.21538,-0.27235 0.6923,-0.18156 1.29229,-0.36311 1.80001,-0.54467 0.55382,-0.22695 0.96921,-0.43121 1.24615,-0.61277 0.32306,-0.18156 0.50767,-0.27234 0.55385,-0.27234 L 896,801.3622"
id="path8204-2"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 948,767.3622 2,0 -15.56048,35 -1.23388,0 -8.70564,-19.62427 -8.70564,19.62427 -1.23388,0 -15.56048,-35 1.50806,0 14.66936,33.04432 8.56854,-19.35453 -5.9637,-13.68979 1.43951,0 5.27823,11.93642 5.27823,-11.93642 1.43951,0 -5.9637,13.68979 8.56854,19.35453 L 948,767.3622"
id="path8206-0"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 970,803.3622 c -2.52363,-0.046 -4.84077,-0.59714 -6.95141,-1.65362 -2.06479,-1.05649 -3.85426,-2.43451 -5.36843,-4.13409 -1.46829,-1.74548 -2.61538,-3.69768 -3.44129,-5.8566 C 953.41296,789.51306 953,787.23932 953,784.89666 c 0,-2.48043 0.4359,-4.84604 1.3077,-7.09684 0.91767,-2.25075 2.13359,-4.22592 3.64777,-5.92551 1.56005,-1.69954 3.37246,-3.03162 5.43724,-3.99628 2.06476,-1.01051 4.26719,-1.51579 6.60729,-1.51583 2.56948,4e-5 4.88661,0.55125 6.95141,1.65363 2.11064,1.10246 3.90011,2.52642 5.36843,4.27189 1.51414,1.74553 2.66123,3.74366 3.44129,5.99441 0.82587,2.20487 1.23883,4.4097 1.23887,6.61453 -4e-5,2.43453 -0.43594,4.7542 -1.3077,6.95903 -0.87183,2.20485 -2.08775,4.15705 -3.64777,5.85661 -1.5142,1.69957 -3.30367,3.05463 -5.36842,4.06518 -2.0648,1.01056 -4.29017,1.53879 -6.67611,1.58472 m -15.62348,-18.46554 c 0.0917,2.20485 0.52766,4.34079 1.30769,6.40782 0.78003,2.06704 1.8583,3.90441 3.23482,5.51211 1.37651,1.56177 2.98245,2.82495 4.81781,3.78956 1.88122,0.91869 3.96895,1.37803 6.26316,1.37803 2.34005,0 4.47365,-0.50527 6.40081,-1.51583 1.9271,-1.01054 3.57891,-2.31967 4.95547,-3.92737 1.37648,-1.65362 2.43181,-3.49099 3.16598,-5.51211 0.73411,-2.06703 1.10118,-4.1111 1.10122,-6.13221 -4e-5,-2.20483 -0.41299,-4.34076 -1.23887,-6.40783 -0.78006,-2.06701 -1.88127,-3.88141 -3.30364,-5.4432 -1.37655,-1.60767 -3.02837,-2.89382 -4.95547,-3.85848 -1.88126,-0.96457 -3.9231,-1.44688 -6.1255,-1.44692 -2.3401,4e-5 -4.4737,0.52828 -6.40081,1.58473 -1.92714,1.01058 -3.57895,2.34268 -4.95547,3.99628 -1.37652,1.60772 -2.43185,3.44509 -3.16598,5.5121 -0.73415,2.02113 -1.10123,4.04223 -1.10122,6.06332"
id="path8208-6"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 1011,767.3622 0,1.34876 c -1.8018,0.09 -3.4459,0.44961 -4.9324,1.079 -1.4865,0.58448 -2.8153,1.39373 -3.9865,2.42774 -1.1262,0.98911 -2.09462,2.1805 -2.90542,3.57418 -1.11712,1.34877 -1.72523,2.83239 -2.17568,4.45087 l 0,22.11945 -1,0 0,-35 1,0 0,9.03662 c 1.79279,-2.83235 3.6396,-5.0353 5.8919,-6.60886 2.2973,-1.61847 5,-2.42772 8.1081,-2.42776"
id="path8210-6"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
<path
d="m 1043,803.3622 -14.8965,-20.34246 -10.1035,8.76712 0,11.57534 -1,0 0,-50 1,0 0,36.57534 24.793,-21.57534 1.8621,0 -15.5171,13.69863 15.862,21.30137 -2,0"
id="path8212-9"
style="fill:#ffffff"
inkscape:connector-curvature="0" />
</g>
<g
transform="translate(-326,-584)"
id="g3895-3"
style="fill:#ffffff">
<path
d="m 688,314.3622 45,110 14,0 45,-110 -12,0 -40,97.78125 -40,-97.78125 z"
transform="translate(-20,308)"
id="path3866-2"
style="fill:#ffffff;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0" />
</g>
<path
d="m 265,38.362205 c -30.31644,0 -55,24.683559 -55,54.999997 0,30.316448 24.68356,54.999998 55,54.999998 30.31644,0 55,-24.68355 55,-54.999998 0,-30.316438 -24.68356,-54.999997 -55,-54.999997 z m 0,9.999999 c 24.91204,0 45,20.087959 45,44.999998 0,24.912048 -20.08796,45.000008 -45,45.000008 -24.91204,0 -45,-20.08796 -45,-45.000008 0,-24.912039 20.08796,-44.999998 45,-44.999998 z"
id="path3905-8"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
inkscape:connector-curvature="0" />
<g
transform="translate(-361,-584)"
id="g3989-3"
style="fill:#ffffff">
<g
transform="translate(-505,0)"
id="g4984-7-6"
style="fill:#ffffff">
<g
transform="translate(499,5)"
id="g3843-8-0-0"
style="font-size:182.75830078px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Raleway;-inkscape-font-specification:Raleway Bold">
<path
d="m 345,314.3622 0,110 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 429.20859,343.1333 435,355.40386 435,374.3622 l 0,50 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 519.20859,343.1333 525,355.40386 525,374.3622 l 0,50 10,0 0,-50 c 0,-21.04166 -6.7086,-36.2711 -16.46875,-46.03125 C 508.7711,318.5708 496.25003,314.3622 485,314.3622 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -4.13742,4.45568 -7.45035,9.98067 -9.875,16.59375 -2.83134,-6.72178 -6.62945,-12.2857 -11.0625,-16.71875 C 418.7711,318.5708 406.25003,314.3622 395,314.3622 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -1.61794,1.74239 -3.10158,3.65009 -4.46875,5.71875 l 0,-19.8125 z"
transform="translate(21,304)"
id="path3790-8-7-8-7"
style="font-size:182.75830078px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Raleway;-inkscape-font-specification:Raleway Bold"
inkscape:connector-curvature="0" />
</g>
</g>
<g
transform="translate(5,0)"
id="g4984-7-7-6"
style="fill:#ffffff">
<g
transform="translate(499,5)"
id="g3843-8-0-3-7"
style="font-size:182.75830078px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Raleway;-inkscape-font-specification:Raleway Bold">
<path
d="m 345,314.3622 0,110 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 429.20859,343.1333 435,355.40386 435,374.3622 l 0,50 10,0 0,-50 c 0,-19.16666 4.73751,-31.50819 11.78125,-39.09375 7.04374,-7.58556 16.71878,-10.90625 28.21875,-10.90625 8.75003,0 18.72891,3.2914 26.46875,11.03125 C 519.20859,343.1333 525,355.40386 525,374.3622 l 0,50 10,0 0,-50 c 0,-21.04166 -6.7086,-36.2711 -16.46875,-46.03125 C 508.7711,318.5708 496.25003,314.3622 485,314.3622 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -4.13742,4.45568 -7.45035,9.98067 -9.875,16.59375 -2.83134,-6.72178 -6.62945,-12.2857 -11.0625,-16.71875 C 418.7711,318.5708 406.25003,314.3622 395,314.3622 c -13.49997,0 -26.32498,4.17931 -35.53125,14.09375 -1.61794,1.74239 -3.10158,3.65009 -4.46875,5.71875 l 0,-19.8125 z"
transform="translate(21,304)"
id="path3790-8-7-8-9-2"
style="font-size:182.75830078px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Raleway;-inkscape-font-specification:Raleway Bold"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</g>
</g>
</svg>

155
app/widgets/Login/login.css

@ -0,0 +1,155 @@
body {
width: 100%;
margin: 0 auto;
max-width: 28em;
}
#content {
margin: 0 auto;
width: 100%;
}
#loginpage {
display: block;
margin: 0 auto;
height: 100%;
background-image: url(img/logo.png);
background-repeat: no-repeat;
background-position: center 1em;
background-size: auto auto;
padding-top: 40%;
margin-top: 40%;
}
#loginpage .admin {
position: fixed;
bottom: 0px;
right: 0px;
color: white;
padding: 1em;
}
#loginpage .admin a:link,
#loginpage .admin a:visited {
color: white;
}
#loginpage #warning {
margin-bottom: 0.7em;
}
#loginpage #connectform {
padding: 0.6em;
background-color: rgba(255, 255, 255, 0.2);
/*border: 1px solid rgba(255, 255, 255, 0.1);
border-top: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 4px;
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);*/
border-radius: 0.1em;
}
#loginpage #connectform .element {
display: block;
margin: 0 auto;
padding: 0px;
width: 100%;
min-height: 2.5em;
}
#loginpage #connectform .element:last-child {
min-height: 1em;
}
#loginpage #connectform .element input {
margin: 0px;
border: 0px;
/*border-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.2) rgba(200, 200, 200, 0.3);*/
box-shadow: none;
color: black;
background-color: rgba(255, 255, 255, 0.3);
}
#loginpage #connectform a[name=submit] {
display: block;
text-align: center;
/*margin: 0px 1px;
display: block;
text-align: center;
margin-top: 1px;
border-radius: 1px;
box-shadow: 1px 0px 0px rgba(0, 0, 0, 0.3),
-1px 0px 0px rgba(0, 0, 0, 0.3),
0px 1px 0px rgba(0, 0, 0, 0.4),
0px -1px 0px rgba(0, 0, 0, 0.4);
border: 0px;
border: 1px solid rgba(255, 255, 255, 0.4);
border-top: 1px solid rgba(255, 255, 255, 0.6);
border-bottom: 1px solid rgba(255, 255, 255, 0.4);
background: linear-gradient(top,
rgba(255, 255, 255, 0.2) 0px,
rgba(255, 255, 255, 0.2) 2px,
rgba(255, 255, 255, 0.05) 100%);
background: -moz-linear-gradient(top,
rgba(255, 255, 255, 0.2) 0px,
rgba(255, 255, 255, 0.2) 2px,
rgba(255, 255, 255, 0.05) 100%);
background: -webkit-linear-gradient(top,
rgba(255, 255, 255, 0.2) 0px,
rgba(255, 255, 255, 0.2) 2px,
rgba(255, 255, 255, 0.05) 100%);
background: -o-linear-gradient(top,
rgba(255, 255, 255, 0.2) 0px,
rgba(255, 255, 255, 0.2) 2px,
rgba(255, 255, 255, 0.05) 100%);
background-color: #76AB16;
text-shadow: -1px -1px 0px rgba(0, 0, 0, 0.4);
color: white;*/
}
#connectform a[name=submit]:before {
color: white;
}
#loginpage .infos {
color: white;
text-align: center;
}
#loginpage #loginhelp {
list-style-type: none;
color: white;
line-height: 1.2em;
text-align: justify;
transition: height 1s ease;
height: 0em;
overflow: hidden;
}
#loginpage #loginhelp li {
height: 2.5em;
background-repeat: no-repeat;
background-image: url(img/beaker.png);
padding-left: 2.5em;
background-position: 0.2em center;
margin: 0.5em 0em;
}
#loginpage #connectform:hover > #loginhelp {
height: 9em;
}
#loginpage #loginhelp li#jabber { background-image: url(img/jabber.png); }
#loginpage #loginhelp li#gmail { background-image: url(img/envelope.png); }
#loginpage #loginhelp li#facebook { background-image: url(img/facebook.png); }
#footer {
display: none;
}

12
app/widgets/Login/login.js

@ -0,0 +1,12 @@
function enterMovim(url) {
window.location.href = url;
}
function loginButtonSet(val, loading) {
document.querySelector('#submit').innerHTML = val;
}
function fillExample(login, pass) {
document.querySelector('#login').value = login;
document.querySelector('#pass').value = pass;
}

125
app/widgets/Logout/Logout.php

@ -0,0 +1,125 @@
<?php
/**
* @package Widgets
*
* @file Logout.php
* This file is part of MOVIM.
*
* @brief The little logout widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Logout extends WidgetBase
{
function WidgetLoad()
{
$this->addcss('logout.css');
$this->addjs('logout.js');
$this->registerEvent('mypresence', 'onMyPresence');
}
function onMyPresence()
{
$html = $this->preparePresence();
RPC::call('movim_fill', 'logout', $html);
RPC::commit();
}
function onPostDisconnect($data)
{
RPC::call('movim_reload',
BASE_URI."index.php?q=disconnect");
}
function ajaxLogout()
{
$presence = Cache::c('presence');
Cache::c(
'presence',
array(
'status' => $presence['status'],
'show' => $presence['show']
)
);
$this->xmpp->logout();
}
function ajaxSetStatus($show)
{
// We update the cache with our status and presence
$presence = Cache::c('presence');
if($show == "boot") $show = $presence['show'];
Cache::c(
'presence',
array(
'status' => $presence['status'],
'show' => $show
)
);
switch($show) {
case 'chat':
$p = new moxl\PresenceChat();
$p->setStatus($presence['status'])->request();
break;
case 'away':
$p = new moxl\PresenceAway();
$p->setStatus($presence['status'])->request();
break;
case 'dnd':
$p = new moxl\PresenceDND();
$p->setStatus($presence['status'])->request();
break;
case 'xa':
$p = new moxl\PresenceXA();
$p->setStatus($presence['status'])->request();
break;
}
}
function preparePresence()
{
$txt = getPresences();
$txts = getPresencesTxt();
global $session;
$pd = new \modl\PresenceDAO();
$p = $pd->getPresence($this->user->getLogin(), $session['ressource']);
$html = '<div id="logouttab" class="'.$txts[$p->presence].'" onclick="showLogoutList();">'.$txt[$p->presence].'</div>';
$html .= '
<div id="logoutlist">
<a onclick="'.$this->genCallAjax('ajaxSetStatus', "'chat'").'; hideLogoutList();" class="online">'.$txt[1].'</a>
<a onclick="'.$this->genCallAjax('ajaxSetStatus', "'away'").'; hideLogoutList();" class="away">'.$txt[2].'</a>
<a onclick="'.$this->genCallAjax('ajaxSetStatus', "'dnd'").'; hideLogoutList();" class="dnd">'.$txt[3].'</a>
<a onclick="'.$this->genCallAjax('ajaxSetStatus', "'xa'").'; hideLogoutList();" class="xa">'.$txt[4].'</a>
</div>
';
return $html;
}
function build()
{
?>
<div id="logout">
<?php echo $this->preparePresence(); ?>
</div>
<?php
}
}
?>

BIN
app/widgets/Logout/img/away.png

After

Width: 10  |  Height: 10  |  Size: 436 B

BIN
app/widgets/Logout/img/dnd.png

After

Width: 10  |  Height: 10  |  Size: 398 B

0
themes/movim/img/icons/door_open.png → app/widgets/Logout/img/door_open.png

Before

Width: 16  |  Height: 16  |  Size: 367 B

After

Width: 16  |  Height: 16  |  Size: 367 B

BIN
app/widgets/Logout/img/online.png

After

Width: 10  |  Height: 10  |  Size: 391 B

BIN
app/widgets/Logout/img/xa.png

After

Width: 10  |  Height: 10  |  Size: 432 B

60
app/widgets/Logout/logout.css

@ -0,0 +1,60 @@
#logout {
font-size: 1em;
color: #ccc;
}
#logout .online { background-image: url(img/online.png); }
#logout .away { background-image: url(img/away.png); }
#logout .dnd { background-image: url(img/dnd.png); }
#logout .xa { background-image: url(img/xa.png); }
#logouttab {
position: fixed;
top: 0px;
right: 50%;
margin-right: -250px;
cursor: pointer;
z-index: 5;
line-height: 3em;
padding-left: 3em;
padding-right: 1em;
background-repeat: no-repeat;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-position: 1em center;
color: white;
}
#logouttab:hover {
background-color: #46565E;
}
#logoutlist {
display: none;
position: fixed;
top: 3em;
right: 50%;
margin-right: -300px;
z-index: 1;
background-color: #4C5A61;
overflow: hidden;
width: 200px;
}
#logoutlist a {
display: block;
line-height: 3em;
background-repeat: no-repeat;
background-position: 0.5em center;
padding-left: 2em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: white;
}
#logoutlist a:hover {
cursor: pointer;
background-color: #46565E;
}

9
app/widgets/Logout/logout.js

@ -0,0 +1,9 @@
function showLogoutList() {
hideNotifsList();
movim_toggle_display('#logoutlist');
}
function hideLogoutList() {
document.getElementById('logoutlist').style.display = 'none';
}

158
app/widgets/Media/Media.php

@ -0,0 +1,158 @@
<?php
/**
* @package Widgets
*
* @file Media.php
* This file is part of MOVIM.
*
* @brief The media manager.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 07 December 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Media extends WidgetBase {
function WidgetLoad()
{
$this->addcss('media.css');
$this->addjs('media.js');
if(!is_dir($this->user->userdir)) {
mkdir($this->user->userdir);
touch($this->user->userdir.'index.html');
}
$this->registerEvent('media', 'onMediaUploaded');
}
function ajaxRefreshMedia()
{
$html = $this->mainFolder();
RPC::call('movim_fill', 'media', $html);
RPC::commit();
}
function ajaxDeleteItem($name)
{
unlink($this->user->userdir.'thumb_'.$name);
unlink($this->user->userdir.'medium_'.$name);
unlink($this->user->userdir.$name);
$this->ajaxRefreshMedia();
}
function listFiles()
{
$html = '<ul class="thumb">';
foreach(scandir($this->user->userdir) as $s) {
if(
$s != '.' &&
$s != '..' &&
substr($s, 0, 6) != 'thumb_' &&
substr($s, 0, 7) != 'medium_' &&
$s != 'index.html')
$html .=
'<li style="background-image: url('.$this->user->useruri.'thumb_'.$s.');">
<a href="?q=media&f='.$s.'">
</a>
<div class="remove" onclick="'.$this->genCallAjax('ajaxDeleteItem', "'".$s."'").'">x</div>
</li>
';
}
$html .= '</ul>';
return $html;
}
function mainFolder()
{
$percent = number_format(($this->user->dirSize()/$this->user->sizelimit)*100, 2);
$html =
$this->listFiles().'
<span class="size">
'.sizeToCleanSize($this->user->dirSize()).' '.t('on').' '.sizeToCleanSize($this->user->sizelimit).
' - '.
$percent.'%
</span>';
return $html;
}
function pictureViewer($f)
{
if(file_exists($this->user->userdir.$f) && getimagesize($this->user->userdir.$f) != 0) {
$er = @exif_read_data($this->user->userdir.$f);
$exif = '';
if($er) {
if(isset($er['FileName']))
$exif .= '<li><span>'.t('Name').'</span>'.$er['FileName'].'</li>';
if(isset($er['COMPUTED']['Width']) && isset($er['COMPUTED']['Height']))
$exif .= '<li><span>'.t('Resolution').'</span>'.$er['COMPUTED']['Width'].'x'.$er['COMPUTED']['Height'].'</li>';
if(isset($er['FileSize']))
$exif .= '<li><span>'.t('Size').'</span>'.sizeToCleanSize($er['FileSize']).'</li>';
if(isset($er['DateTime']))
$exif .= '<li><span>'.t('Date').'</span>'.prepareDate(strtotime($er['DateTime'])).'</li>';
if(isset($er['ISOSpeedRatings']))
$exif .= '<li><span>'.t('ISO').'</span>'.$er['ISOSpeedRatings'].'</li>';
if(isset($er['Model']))
$exif .= '<li><span>'.t('Camera').'</span>'.$er['Model'].'</li>';
if(isset($er['Artist']))
$exif .= '<li><span>'.t('Artist').'</span>'.$er['Artist'].'</li>';
}
$exif .= '<li><span>'.t('Original').'</span><a target="_blank" href="'.$this->user->useruri.$f.'">'.t('Link').'</a></li>';
$html = '
<div class="viewer">
<img src="'.$this->user->useruri.'medium_'.$f.'"/>
<div class="exif">
<ul>
'.$exif.'
</ul>
</div>
</div>';
return $html;
}
}
function build()
{
$refresh = $this->genCallAjax('ajaxRefreshMedia');
?>
<script type="text/javascript">
function refreshMedia() {
<?php echo $refresh; ?>
}
</script>
<?php
if(isset($_GET['f'])) {
?>
<div class="tabelem" title="<?php echo t('Viewer'); ?>" id="viewer">
<?php echo $this->pictureViewer($_GET['f']); ?>
</div>
<?php
}
?>
<div class="tabelem" title="<?php echo t('Media'); ?>" id="media">
<?php echo $this->mainFolder(); ?>
</div>
<?php
}
}

BIN
app/widgets/Media/img/paper.png

After

Width: 100  |  Height: 100  |  Size: 7.9 KiB

115
app/widgets/Media/media.css

@ -0,0 +1,115 @@
#main {
}
#center {
position: relative;
}
#navtabs, #navtabs li.on {
background-color: transparent;
color: white;
}
#navtabs li.on {
background-color: #111;
}
#media .breadcrumb {
background-color: transparent;
}
#media .breadcrumb a:after {
border-color: #222;
}
#media ul.thumb a {
position: relative;
}
#media ul.thumb li div.remove {
position: absolute;
bottom: 0px;
right: 0px;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 3px 0px 0px 0px;
font-weight: bold;
width: 26px;
height: 26px;
text-align: center;
line-height: 26px;
font-size: 16px;
display: none;
}
#media ul.thumb li:hover div.remove {
display: block;
}
#media ul.thumb li:hover div.remove:hover {
background-color: black;
cursor: pointer;
}
#media a:link, #media a:visited,
#viewer a:link, #viewer a:visited {
color: #DDD;
}
#navtabs li:hover {
background-color: #111;
}
#center {
background-color: #222;
color: white;
}
#viewer .viewer {
position: relative;
}
#viewer .viewer img {
width: 100%;
height: auto;
display: block;
}
#viewer .viewer .exif {
position: absolute;
bottom: 0px;
background-color: rgba(0, 0, 0, 0.8);
width: 100%;
padding: 1em;
}
#viewer .viewer .exif ul {
list-style-type: none;
}
#viewer .viewer .exif ul li {
width: 50%;
display: block;
float: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#viewer .viewer .exif span {
font-weight: bold;
display: inline-block;
text-align: right;
margin-right: 1em;
width: 5em;
}
#media .size {
position: absolute;
font-size: 0.9em;
top: 0px;
right: 0px;
line-height: 3em;
display: block;
padding-right: 1em;
}

181
app/widgets/Media/media.js

@ -0,0 +1,181 @@
// common variables
var iBytesUploaded = 0;
var iBytesTotal = 0;
var iPreviousBytesLoaded = 0;
var iMaxFilesize = 1048576; // 1MB
var oTimer = 0;
var sResultFileSize = '';
function secondsToTime(secs) { // we will use this function to convert seconds in normal time format
var hr = Math.floor(secs / 3600);
var min = Math.floor((secs - (hr * 3600))/60);
var sec = Math.floor(secs - (hr * 3600) - (min * 60));
if (hr < 10) {hr = "0" + hr; }
if (min < 10) {min = "0" + min;}
if (sec < 10) {sec = "0" + sec;}
if (hr) {hr = "00";}
return hr + ':' + min + ':' + sec;
};
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
function fileSelected() {
// hide different warnings
document.getElementById('upload_response').style.display = 'none';
document.getElementById('error').style.display = 'none';
document.getElementById('error2').style.display = 'none';
document.getElementById('abort').style.display = 'none';
document.getElementById('warnsize').style.display = 'none';
// get selected file element
var oFile = document.getElementById('image_file').files[0];
document.getElementById('uploadbutton').style.display = 'inline-block';
var img = new Image;
img.onerror = function() {
document.getElementById('error').style.display = 'block';
document.getElementById('uploadbutton').style.display = 'none';
return;
};
// little test for filesize
if (oFile.size > iMaxFilesize) {
document.getElementById('warnsize').style.display = 'block';
document.getElementById('uploadbutton').style.display = 'none';
return;
}
// get preview element
var oImage = document.getElementById('preview');
// prepare HTML5 FileReader
var oReader = new FileReader();
oReader.onload = function(e){
img.src = e.target.result;
// e.target.result contains the DataURL which we will use as a source of the image
oImage.src = e.target.result;
oImage.onload = function () { // binding onload event
// we are going to display some custom image information here
sResultFileSize = bytesToSize(oFile.size);
document.getElementById('fileinfo').style.display = 'block';
document.getElementById('filename').innerHTML = 'Name: ' + oFile.name;
document.getElementById('filesize').innerHTML = 'Size: ' + sResultFileSize;
document.getElementById('filetype').innerHTML = 'Type: ' + oFile.type;
document.getElementById('filedim').innerHTML = 'Dimension: ' + oImage.naturalWidth + ' x ' + oImage.naturalHeight;
};
};
// read selected file as DataURL
oReader.readAsDataURL(oFile);
}
function startUploading() {
// cleanup all temp states
iPreviousBytesLoaded = 0;
document.getElementById('upload_response').style.display = 'none';
document.getElementById('error').style.display = 'none';
document.getElementById('error2').style.display = 'none';
document.getElementById('abort').style.display = 'none';
document.getElementById('warnsize').style.display = 'none';
document.getElementById('progress_percent').innerHTML = '';
var oProgress = document.getElementById('progress');
oProgress.style.display = 'block';
oProgress.style.width = '0px';
// get form data for POSTing
var vFD = new FormData(document.getElementById('upload_form'));
// create XMLHttpRequest object, adding few event listeners, and POSTing our data
var oXHR = new XMLHttpRequest();
oXHR.upload.addEventListener('progress', uploadProgress, false);
oXHR.addEventListener('load', uploadFinish, false);
oXHR.addEventListener('error', uploadError, false);
oXHR.addEventListener('abort', uploadAbort, false);
oXHR.open('POST', 'upload.php');
oXHR.send(vFD);
// set inner timer
oTimer = setInterval(doInnerUpdates, 300);
}
function doInnerUpdates() { // we will use this function to display upload speed
var iCB = iBytesUploaded;
var iDiff = iCB - iPreviousBytesLoaded;
// if nothing new loaded - exit
if (iDiff == 0)
return;
iPreviousBytesLoaded = iCB;
iDiff = iDiff * 2;
var iBytesRem = iBytesTotal - iPreviousBytesLoaded;
var secondsRemaining = iBytesRem / iDiff;
// update speed info
var iSpeed = iDiff.toString() + 'B/s';
if (iDiff > 1024 * 1024) {
iSpeed = (Math.round(iDiff * 100/(1024*1024))/100).toString() + 'MB/s';
} else if (iDiff > 1024) {
iSpeed = (Math.round(iDiff * 100/1024)/100).toString() + 'KB/s';
}
document.getElementById('speed').innerHTML = iSpeed;
document.getElementById('remaining').innerHTML = ' ' + secondsToTime(secondsRemaining);
}
function uploadProgress(e) { // upload process in progress
if (e.lengthComputable) {
iBytesUploaded = e.loaded;
iBytesTotal = e.total;
var iPercentComplete = Math.round(e.loaded * 100 / e.total);
var iBytesTransfered = bytesToSize(iBytesUploaded);
document.getElementById('progress_percent').innerHTML = iPercentComplete.toString() + '%';
document.getElementById('progress').style.width = (iPercentComplete * 4).toString() + 'px';
document.getElementById('b_transfered').innerHTML = iBytesTransfered;
if (iPercentComplete == 100) {
var oUploadResponse = document.getElementById('upload_response');
oUploadResponse.innerHTML = '<h1>Please wait...processing</h1>';
oUploadResponse.style.display = 'block';
}
} else {
document.getElementById('progress').innerHTML = 'unable to compute';
}
}
function uploadFinish(e) { // upload successfully finished
var oUploadResponse = document.getElementById('upload_response');
oUploadResponse.innerHTML = e.target.responseText;
oUploadResponse.style.display = 'block';
document.getElementById('progress_percent').innerHTML = '100%';
document.getElementById('progress').style.width = '400px';
document.getElementById('filesize').innerHTML = sResultFileSize;
document.getElementById('remaining').innerHTML = ' 00:00:00';
clearInterval(oTimer);
refreshMedia();
}
function uploadError(e) { // upload error
document.getElementById('error2').style.display = 'block';
clearInterval(oTimer);
}
function uploadAbort(e) { // upload abort
document.getElementById('abort').style.display = 'block';
clearInterval(oTimer);
}

86
app/widgets/MediaUpload/MediaUpload.php

@ -0,0 +1,86 @@
<?php
/**
* @package Widgets
*
* @file MediaUpload.php
* This file is part of MOVIM.
*
* @brief The media upload.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 07 December 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class MediaUpload extends WidgetBase {
function WidgetLoad()
{
$this->addcss('mediaupload.css');
}
function build()
{
if($this->user->dirSize() < $this->user->sizelimit) {
?>
<div class="tabelem padded" title="<?php echo t('Upload'); ?>" id="mediaupload">
<form id="upload_form" enctype="multipart/form-data" method="post" action="upload.php">
<fieldset>
<div class="element">
<label for="image_file"><?php echo t('Please select image file'); ?></label>
<input type="file" name="image_file" id="image_file" onchange="fileSelected();" />
</div>
<img id="preview" />
<div id="fileinfo">
<div id="filename"></div>
<div id="filesize"></div>
<div id="filetype"></div>
<div id="filedim"></div>
</div>
<div class="clear"></div>
<div id="progress_info">
<div id="progress"></div>
<div id="progress_percent"></div>
<div class="clear_both"></div>
<div>
<div id="speed"></div>
<div id="remaining"></div>
<div id="b_transfered"></div>
<div class="clear_both"></div>
</div>
<div id="upload_response"></div>
</div>
</fieldset>
<div class="clear"></div>
<a id="uploadbutton" class="button icon color green upload" onclick="startUploading()" /><?php echo t('Upload'); ?></a>
<div class="message info" id="error">
<?php echo t('You should select valid image files only!'); ?>
</div>
<div class="message error" id="error2">
<?php echo t('An error occurred while uploading the file'); ?>
</div>
<div class="message info" id="abort">
<?php echo t('The upload has been canceled by the user or the browser dropped the connection'); ?>
</div>
<div class="message info" id="warnsize">
<?php echo t("Your file is very big. We can't accept it. Please select a smaller file"); ?>
</div>
</form>
</div>
<?php
}
}
}

28
app/widgets/MediaUpload/mediaupload.css

@ -0,0 +1,28 @@
#mediaupload #fileinfo {
clear: left;
}
#progress_info {
margin-top: 1em;
}
#fileinfo,#error,#error2,#abort,#warnsize {
display:none;
}
#progress {
margin-right: 1em;
display:none;
float:left;
height:16px;
background-color: #111;
}
#progress_percent {
float:right;
}
#mediaupload #preview {
display:block;
float:right;
max-width: 200px;
max-height: 150px;
margin-top: 1em;
}

240
app/widgets/Node/Node.php

@ -0,0 +1,240 @@
<?php
/**
* @package Widgets
*
* @file Node.php
* This file is part of MOVIM.
*
* @brief The items of a node
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Node extends WidgetCommon
{
function WidgetLoad()
{
$this->registerEvent('stream', 'onStream');
$this->registerEvent('nostream', 'onStream');
$this->registerEvent('pubsubsubscribed', 'onPubsubSubscribed');
$this->registerEvent('pubsubsubscribederror', 'onPubsubSubscribedError');
$this->registerEvent('pubsubunsubscribed', 'onPubsubUnsubscribed');
}
function onPubsubSubscribed($params)
{
$html = $this->prepareGroup($params[0], $params[1]);
RPC::call('setBookmark');
RPC::call('movim_fill', 'node', $html);
RPC::call('movim_reload_this');
}
function onPubsubSubscribedError($params)
{
$this->onPubsubSubscribed($params);
}
function onPubsubUnsubscribed($params)
{
$this->onPubsubSubscribed($params);
}
function onStream($payload) {
$html = $this->prepareGroup($payload['from'], $payload['node']);
if($html == '')
$html = t("Your feed cannot be loaded.");
RPC::call('movim_fill', md5($payload['from'].$payload['node']), $html);
}
function ajaxGetItems($server, $node)
{
$r = new moxl\PubsubGetItems();
$r->setTo($server)
->setNode($node)
->request();
}
function ajaxSubscribe($data, $server, $node)
{
$g = new moxl\PusubSubscribe();
$g->setTo($server)
->setNode($node)
->setFrom($this->user->getLogin())
->setData($data)
->request();
}
function ajaxUnsubscribe($server, $node)
{
$sd = new \modl\SubscriptionDAO();
foreach($sd->get($server, $node) as $s) {
$g = new moxl\PubsubUnsubscribe();
$g->setTo($server)
->setNode($node)
->setSubid($s->subid)
->setFrom($this->user->getLogin())
->request();
}
}
function ajaxGetSubscriptions($server, $node)
{
$r = new moxl\PubsubGetSubscriptions();
$r->setTo($server)
->setNode($node)
->request();
}
function prepareGroup($serverid, $groupid) {
if($this->searchSubscription($serverid, $groupid))
$button = '
<a
href="#"
class="button color icon back"
onclick="movim_toggle_display(\'#groupunsubscribe\')">
'.t('Unsubscribe').'
</a>';
else
$button = '
<a
href="#"
class="button color green icon next"
onclick="movim_toggle_display(\'#groupsubscribe\')">
'.t('Subscribe').'
</a>';
$html = '
<div class="breadcrumb">
<a href="'.Route::urlize('explore').'">
'.t('Explore').'
</a>
<a href="'.Route::urlize('server', $serverid).'">
'.$serverid.'
</a>
<a href="'.Route::urlize('node', array($serverid, $groupid)).'">
'.$groupid.'
</a>
<a>'.t('Posts').'</a>
</div>
<div class="posthead">
'.$button.'
<a
href="#"
onclick="'.$this->genCallAjax('ajaxGetItems', "'".$serverid."'", "'".$groupid."'").'
this.className=\'button tiny icon loading\'; this.onclick=null;"
class="button color blue icon refresh">
'.('Refresh').'
</a>
<a
class="button color orange icon yes"
onclick="
'.$this->genCallAjax('ajaxGetSubscriptions', "'".$serverid."'", "'".$groupid."'").'"
>'.t('Get Subscription').'</a>
</div>
<div class="popup" id="groupsubscribe">
<form name="groupsubscribe">
<fieldset>
<legend>'.t('Subscribe').'</legend>
<div class="element large mini">
<input type="checkbox" name="listgroup" id="listgroup"/>
<span><label for="listgroup">'.t('Make your membership to this group public to your friends').'</label></span>
</div>
<div class="element large mini">
<input type="text" name="title" value="'.$groupid.'" id="grouptitle"/>
<span><label for="grouptitle">'.t('Give a nickname to this group if you want').'</label></span>
</div>
</fieldset>
<a
class="button tiny icon yes black merged left"
onclick="
'.$this->genCallAjax('ajaxSubscribe', "movim_parse_form('groupsubscribe')", "'".$serverid."'", "'".$groupid."'").'
this.onclick=null;"
>'.t('Subscribe').'</a><a
class="button tiny icon black merged right"
onclick="
movim_toggle_display(\'#groupsubscribe\');"
>'.t('Close').'</a>
</form>
</div>
<div class="popup" id="groupunsubscribe">
<form name="groupunsubscribe">
<fieldset>
<legend>'.t('Unsubscribe').'</legend>
<div class="element large mini">
<span>'.t('Are you sure ?').'</span>
</div>
</fieldset>
<a
class="button tiny icon yes black merged left"
onclick="
'.$this->genCallAjax('ajaxUnsubscribe', "'".$serverid."'", "'".$groupid."'").'
this.onclick=null;"
>'.t('Unsubscribe').'</a><a
class="button tiny icon black merged right"
onclick="
movim_toggle_display(\'#groupunsubscribe\');"
>'.t('Close').'</a>
</form>
</div>';
$title = '';
$pd = new modl\PostnDAO();
$posts = $pd->getNode($serverid, $groupid, 0, 10);
$html .= $title;
if($this->searchSubscription($serverid, $groupid))
$html .= $this->prepareSubmitForm($serverid, $groupid);
$html .= $this->preparePosts($posts);
return $html;
}
function searchSubscribed($server, $node) {
$c = Cache::c('bookmark');
foreach($c as $bookmark) {
if(
$bookmark['type'] == 'subscription' &&
$bookmark['server'] == $server &&
$bookmark['node'] == $node) {
return true;
}
}
return false;
}
function searchSubscription($server, $node) {
$sd = new \modl\SubscriptionDAO();
foreach($sd->get($server, $node) as $s) {
if($s->subscription == 'subscribed')
return true;
}
return false;
}
function build()
{
?>
<div class="tabelem protect red" id="node" title="<?php echo t('Posts'); ?>">
<div id="<?php echo md5($_GET['s'].$_GET['n']); ?>">
<?php echo $this->prepareGroup($_GET['s'], $_GET['n']); ?>
</div>
</div>
<?php
}
}

103
app/widgets/NodeAffiliations/NodeAffiliations.php

@ -0,0 +1,103 @@
<?php
/**
* @package Widgets
*
* @file NodeAffiliations.php
* This file is part of MOVIM.
*
* @brief A widget for retrieving your group's members
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 17 April 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class NodeAffiliations extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('pubsubaffiliations', 'onGroupMemberList');
$this->registerEvent('pubsubaffiliationssubmited', 'onSubmit');
}
function prepareList($list) { //0:data 1:server 2:node
$affiliation = array("owner", "member", "none");
$html = '<form id="affiliationsManaging">';
foreach($list[0] as $item){ //0:jid 1:affiliation 2:subid
$html .= '
<div class="element">
<label for="'.$item[0].'_'.$item[2].'"><a href="?q=friend&f='.$item[0].'">'.$item[0].'</a></label>
<div class="select">
<select name="'.$item[0].'_'.$item[2].'">';
foreach($affiliation as $status){
$status == $item[1] ? $selected = "selected" : $selected = "";
$html .= '<option '.$selected.'>'.t($status).'</option>';
}
$html .= ' </select>
</div>
</div>';
}
$ok = $this->genCallAjax('ajaxChangeAffiliation', "'".$list[1]."'", "'".$list[2]."'", "movim_parse_form('affiliationsManaging')");
$html .= '
<hr />
<br />
<a
class="button color green icon yes"
style="float: right;"
onclick="'.$ok.'">
'.t('Validate').'
</a></form>';
return $html;
}
function onSubmit($stanza) {
Notification::appendNotification(t('Affiliations saved'), 'success');
RPC::commit();
}
function onGroupMemberList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'memberlist', $html);
RPC::commit();
}
function ajaxChangeAffiliation($server, $node, $data){
$r = new moxl\PubsubSetAffiliations();
$r->setNode($node)->setTo($server)->setData($data)
->request();
}
function ajaxGetGroupMemberList($server, $node){
$r = new moxl\PubsubGetAffiliations();
$r->setTo($server)->setNode($node)
->request();
}
function build()
{
?>
<div class="tabelem" title="<?php echo t('Manage your members'); ?>" id="groupmemberlist">
<div class="posthead">
<a
class="button icon users color green"
onclick="<?php echo $this->genCallAjax('ajaxGetGroupMemberList', "'".$_GET['s']."'", "'".$_GET['n']."'"); ?> this.parentNode.style.display = 'none'">
<?php echo t("Get the members");?>
</a>
</div>
<div id="memberlist" class="padded"></div>
</div>
<?php
}
}
?>

119
app/widgets/NodeConfig/NodeConfig.php

@ -0,0 +1,119 @@
<?php
/**
* @package Widgets
*
* @file GroupConfig.php
* This file is part of MOVIM.
*
* @brief The Group configuration widget
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 12 March 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class NodeConfig extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('pubsubconfig', 'onConfigForm');
$this->registerEvent('pubsubconfigsubmited', 'onGroupConfig');
$this->registerEvent('deletionsuccess', 'onGroupDeleted');
}
function onGroupDeleted($server) {
$html = '
<a href="?q=server&s='.$server.'">
'.t("Return to %s's list of groups", $server).'
</a><br /><br />';
Notification::appendNotification(t('Group deleted'), 'success');
RPC::call('movim_fill', 'handlingmessages', $html);
RPC::commit();
}
function onGroupConfig($stanza) {
Notification::appendNotification(t('Group configuration saved'), 'success');
RPC::commit();
}
function onConfigForm($form) {
$submit = $this->genCallAjax('ajaxSubmitConfig', "movim_parse_form('config')", "'".$form[1]."'", "'".$form[2]."'");
$html = '
<form name="config">'.
$form[0].
'
<hr /><br />
<a
class="button color green icon yes"
style="float: right;"
onclick="'.$submit.' this.onclick=null;"
>
'.t('Validate').'
</a>
<br />
<br />
</form>';
RPC::call('movim_fill', 'groupconfiguration', $html);
RPC::commit();
}
function ajaxGroupConfig($server, $node){
$r = new moxl\PubsubGetConfig();
$r->setTo($server)
->setNode($node)
->request();
}
function ajaxGroupDelete($server, $node){
$nd = new modl\NodeDAO();
$nd->deleteNode($server, $node);
$r = new moxl\GroupDelete();
$r->setTo($server)
->setNode($node)
->request();
}
function ajaxSubmitConfig($data, $server, $node){
$r = new moxl\PubsubSetConfig();
$r->setTo($server)
->setNode($node)
->setData($data)
->request();
}
function build()
{
?>
<div class="tabelem" title="<?php echo t('Configuration'); ?>" id="groupconfig">
<h1><?php echo t('Configuration'); ?></h1>
<div id="groupconfiguration" class="paddedtop">
<div id="handlingmessages"></div>
<a
class="button color green icon write"
onclick="<?php echo $this->genCallAjax('ajaxGroupConfig', "'".$_GET['s']."'", "'".$_GET['n']."'"); ?> this.style.display = 'none'">
<?php echo t("Configure your group");?>
</a>
<a
class="button color red icon no"
onclick="<?php echo $this->genCallAjax('ajaxGroupDelete', "'".$_GET['s']."'", "'".$_GET['n']."'"); ?> this.style.display = 'none'">
<?php echo t("Delete this group");?>
</a>
</div>
</div>
<?php
}
}
?>

51
app/widgets/Notification/Notification.php

@ -0,0 +1,51 @@
<?php
/**
* @package Widgets
*
* @file Notifs.php
* This file is part of MOVIM.
*
* @brief The notification widget
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 16 juin 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Notification extends WidgetCommon
{
function WidgetLoad()
{
$this->addcss('notification.css');
$this->addjs('notification.js');
$this->registerEvent('pubsuberror', 'onPubsubError');
}
static function appendNotification($message, $type = 'info')
{
$id = $message.rand(0, 1500);
$html = '<div class="notif notificationAnim '.$type.'" id="'.$id.'">'.$message.'</div>';
RPC::call('removeDiff', 'notification', $html);
RPC::commit();
}
function onPubsubError($error) {
Notification::appendNotification($error, 'error');
}
function build()
{
?>
<div id="notification">
</div>
<?php
}
}

BIN
app/widgets/Notification/img/error.png

After

Width: 16  |  Height: 16  |  Size: 246 B

BIN
app/widgets/Notification/img/info.png

After

Width: 16  |  Height: 16  |  Size: 237 B

BIN
app/widgets/Notification/img/success.png

After

Width: 16  |  Height: 16  |  Size: 319 B

BIN
app/widgets/Notification/img/warning.png

After

Width: 16  |  Height: 16  |  Size: 138 B

71
app/widgets/Notification/notification.css

@ -0,0 +1,71 @@
#notification {
position: fixed;
bottom: 0px;
left: 0px;
z-index: 5;
}
#notification .notif {
background-color: rgba(0, 0, 0, 0.8);
width: 20em;
margin: 0.5em;
color: white;
padding: 0.7em;
padding-left: 3em;
opacity: 1;
line-height: 1.5em;
background-repeat: no-repeat;
background-position: 1em center;
background-image: url(img/success.png);
}
#notification .notif.error {
background-image: url(img/error.png);
}
#notification .notif.warning {
background-image: url(img/warning.png);
}
#notification .notif.info {
background-image: url(img/info.png);
}
#notification .notif:hover {
opacity: 0.4;
}
.notificationAnim {
opacity: 0;
visibility: hidden;
position: relative;
-webkit-animation: fadeOut 5s linear;
-moz-animation: fadeOut 5s linear;
-ms-animation: fadeOut 5s linear;
-o-animation: fadeOut 5s linear;
animation: fadeOut 5s linear;
}
@-webkit-keyframes fadeOut {
0% { opacity: 0; visibility: visible; left: 0px; }
5% { opacity: 1; visibility: visible; left: 0px; }
90% { opacity: 1; visibility: visible; left: 0px; }
100% { opacity: 0; visibility: hidden; left: -300px; }
}
@-moz-keyframes fadeOut {
0% { opacity: 0; visibility: visible; left: 0px; }
5% { opacity: 1; visibility: visible; left: 0px; }
90% { opacity: 1; visibility: visible; left: 0px; }
100% { opacity: 0; visibility: hidden; left: -300px; }
}
@-ms-keyframes fadeOut {
0% { opacity: 0; visibility: visible; left: 0px; }
5% { opacity: 1; visibility: visible; left: 0px; }
90% { opacity: 1; visibility: visible; left: 0px; }
100% { opacity: 0; visibility: hidden; left: -300px; }
}

21
app/widgets/Notification/notification.js

@ -0,0 +1,21 @@
function removeDiff(params) {
if(params.length < 2) {
return;
}
var wrapper= document.createElement('div');
wrapper.innerHTML = params[1];
var nodes = wrapper.childNodes;
target = document.getElementById(params[0]);
if(target) {
for(i = 0; i < nodes.length; i++) {
var n = nodes[i];
target.appendChild(n);
setTimeout(function() {
n.parentNode.removeChild(n);
},
6000);
}
}
}

290
app/widgets/Notifs/Notifs.php

@ -0,0 +1,290 @@
<?php
/**
* @package Widgets
*
* @file Notifs.php
* This file is part of MOVIM.
*
* @brief The notification widget
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @version 1.0
* @date 16 juin 2011
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Notifs extends WidgetCommon
{
function WidgetLoad()
{
$this->addcss('notifs.css');
$this->addjs('notifs.js');
$this->registerEvent('notification', 'onNotification');
$this->registerEvent('notificationdelete', 'onNotificationDelete');
$this->registerEvent('notifications', 'displayNotifications');
$this->registerEvent('nonotification', 'onNoNotification');
}
/*
* Retrieve all the notifications
*/
function ajaxGetNotifications() {
$p = new moxl\NotificationGet();
$p->setTo($this->user->getLogin())
->request();
}
/*
* Delete a notification item
*/
function ajaxDeleteNotification($id) {
$d = new moxl\NotificationItemDelete();
$d->setTo($this->user->getLogin())
->setId($id)
->request();
}
/*
* Create the notification element from the inbox item
* @param SimpleXMLElement $item
*/
function onNotification($item) {
$arr = explodeURI((string)$item->entry->link[0]->attributes()->href);
$post = end(explode('/', $arr['node']));
$notifs = Cache::c('activenotifs');
$request = $this->genCallAjax(
"ajaxGetComments",
"'".$this->user->getLogin()."'",
"'".$post."'");
$delete = $this->genCallAjax(
"ajaxDeleteNotification",
"'".(string)$item->attributes()->id."'");
$nhtml = '
<li>
<a href="?q=friend&f='.$arr['path'].'&p='.$post.'"
onclick="'.$request.'">
<span style="font-weight: bold;">'.
(string)$item->entry->source->author->name.'
</span> - '.prepareDate(strtotime((string)$item->entry->published)).'<br />'.
(string)$item->entry->content.'
</a>
<a class="delete" href="#" onclick="'.$delete.'">'.t('Delete').'</a>
<div class="clear"></div>
</li>
';
$notifs[(string)$item->attributes()->id] = $nhtml;
Cache::c('activenotifs', $notifs);
}
/*
* In notification deletion
* @param string $id
*/
function onNotificationDelete($id) {
$notifs = Cache::c('activenotifs');
unset($notifs[$id]);
Cache::c('activenotifs', $notifs);
RPC::call('movim_fill', 'notifs', $this->prepareNotifs());
}
/*
* Display all the notifications to the browser
*/
function displayNotifications() {
RPC::call('movim_fill', 'notifs', $this->prepareNotifs());
}
/*
* Display all the notifications to the browser if there is no new
* notifications
*/
function onNoNotification() {
RPC::call('movim_fill', 'notifs', $this->prepareNotifs());
}
/*
* Create the list of notifications
* @return string
*/
function prepareNotifs()
{
$notifsnum = 0;
$html .= '
<div id="notifslist">
<a
class="button icon color green refresh"
href="#"
style="margin: 0.5em;"
onclick="'.$this->genCallAjax("ajaxGetNotifications").';
this.innerHTML = \''.t('Updating').'\';
this.className= \'button tiny icon loading black\';
this.onclick=null;">
'.t('Refresh').'
</a>
<ul>';
// XMPP notifications
$notifs = Cache::c('activenotifs');
if($notifs == false)
$notifs = array();
if(sizeof($notifs) != 0) {
$notifsnum += sizeof($notifs);
$html .= '
<li class="title">'.
t('Notifications').'
<span class="num">'.sizeof($notifs).'</span>
</li>';
foreach($notifs as $n => $val) {
if($val == 'sub')
$html .= $this->prepareNotifInvitation($n);
else
$html .= $val;
}
}
// Contact request pending
$cd = new \modl\ContactDAO();
$subscribes = $cd->getRosterSubscribe();
if(sizeof($subscribes) != 0) {
$notifsnum += sizeof($subscribes);
$html .= '
<li class="title">'.
t('Contact request pending').'
<span class="num">'.sizeof($subscribes).'</span>
</li>';
foreach($subscribes as $s) {
$html .= '
<li>
<a href="?q=friend&f='.$s->jid.'">
<img class="avatar" src="'.$s->getPhoto('s').'" />
'.
$s->getTrueName().'
</a>
</li>';
}
}
$html .= '
</ul>
</div>';
$notifsnew = '';
if($notifsnum > 0)
$notifsnew = 'class="red"';
$html = '
<div id="notifstab" onclick="showNotifsList();">
<span '.$notifsnew.'>'.
$notifsnum.'
</span>
</div>'.$html;
return $html;
}
function ajaxSubscribed($jid) {
$p = new moxl\PresenceSubscribed();
$p->setTo($jid)
->request();
}
function ajaxRefuse($jid) {
$p = new moxl\PresenceUnsubscribed();
$p->setTo($jid)
->request();
$notifs = Cache::c('activenotifs');
unset($notifs[$jid]);
Cache::c('activenotifs', $notifs);
RPC::call('movim_fill', 'notifs', $this->prepareNotifs());
RPC::commit();
}
function ajaxAccept($jid, $alias) {
$r = new moxl\RosterAddItem();
$r->setTo($jid)
->request();
$p = new moxl\PresenceSubscribe();
$p->setTo($jid)
->request();
$p = new moxl\PresenceSubscribed();
$p->setTo($jid)
->request();
$notifs = Cache::c('activenotifs');
unset($notifs[$jid]);
Cache::c('activenotifs', $notifs);
RPC::call('movim_fill', 'notifs', $this->prepareNotifs());
RPC::commit();
}
/*
* Prepare a notification for incoming invitation
* @return string
*/
function prepareNotifInvitation($from) {
$html .= '
<li>
<form id="acceptcontact">
<p>'.$from.' '.t('wants to talk with you'). '</p>
<a
class="button tiny icon add merged right black"
href="#" id="notifsvalidate"
onclick="'.$this->genCallAjax("ajaxAccept", "'".$from."'", "'alias'").'">'.
t("Add").'
</a><a
class="button tiny icon no merged left black"
href="#"
onclick="'.$this->genCallAjax("ajaxRefuse", "'".$from."'").'">'.
t("Decline").'
</a>
</form>
<div class="clear"></div>
</li>';
return $html;
}
function build()
{
?>
<div id="notifs">
<?php echo $this->prepareNotifs(); ?>
</div>
<?php
}
}

134
app/widgets/Notifs/notifs.css

@ -0,0 +1,134 @@
#notifs {
color: #ccc;
}
#notifstab {
position: fixed;
top: 0px;
right: 50%;
margin-right: -300px;
cursor: pointer;
z-index: 4;
padding: 0.8em 0.5em;
}
#notifs span {
color: white;
font-size: 0.8em;
padding: 0px;
line-height: 1.7em;
float: right;
padding: 0px 1em;
border-radius: 0.1em;
background-color: #444;
}
#notifstab span.red {
background-color: #D92727;
}
#notifstab:hover {
color: white;
}
#notifstab:hover:after {
background-color: #888;
}
#notifslist #acceptcontact p {
padding: 0.5em;
}
#notifslist {
display: none;
position: fixed;
top: 3em;
right: 50%;
margin-right: -300px;
z-index: 3;
background-color: #4C5A61;
overflow: hidden;
max-height: 400px;
width: 300px;
overflow-y: auto;
overflow-x: hidden;
}
#notifslist ul li:hover .black {
color: #BBB;
}
#notifslist #refresh:before {
color: #BBB;
}
#notifslist ul {
list-style-type: none;
clear: both;
}
#notifslist ul li {
line-height: 2em;
width: 100%;
display: block;
}
#notifslist ul li:nth-child(2n) {
background-color: rgba(255, 255, 255, 0.03);
}
#notifslist ul li p {
line-height: 1em;
padding: 0em 0.5em;
}
#notifslist ul li a#notifsvalidate {
margin-right: 0.5em;
}
#notifslist ul li span.num {
background-color: #D92727;
margin: 0.4em;
}
#notifslist ul li:hover {
color: black;
}
#notifslist ul li.title {
text-align: center;
border-top: none;
color: white;
}
#notifslist ul li.title:hover {
color: white;
background-color: #242424;
color: white;
}
#notifslist ul li img {
max-width: 2em;
float: left;
margin-right: 0.5em;
}
#notifslist ul li a {
color: #ccc;
overflow: hidden;
text-overflow: ellipsis;
display: block;
}
#notifslist ul li a.delete {
float: right;
margin-right: 10px;
}
#notifslist ul li a.delete:hover {
text-decoration: underline;
}
#notifslist ul li:hover a {
color: black;
}

64
app/widgets/Notifs/notifs.js

@ -0,0 +1,64 @@
function showNotifsList() {
hideLogoutList();
movim_toggle_display('#notifslist');
}
function hideNotifsList() {
document.getElementById('notifslist').style.display = 'none';
}
/*function hideNotification(n) {
n.parentNode.parentNode.removeChild(n.parentNode);
}
function showAlias(n) {
n.style.display = "none";
document.querySelector('#notifsvalidate').style.display = "block";
document.querySelector('#labelnotifsalias').style.display = "block";
document.querySelector('#notifsalias').style.display = "block";
}
function addJid(n) {
document.querySelector('#addcontact').style.display = "block";
}
function cancelAddJid() {
document.querySelector('#addcontact').style.display = "none";
}
function getAlias() {
return document.querySelector('#notifsalias').value;
}
function getAddJid() {
return document.querySelector('#addjid').value;
}
function getAddAlias() {
return document.querySelector('#addalias').value;
}
function RequestPermission (callback)
{
window.webkitNotifications.requestPermission(callback);
}
function notification(params)
{
if (window.webkitNotifications.checkPermission() > 0) {
RequestPermission(notification);
}
if(document_focus == false) {
var icon = '';
var title = params[0];
var body = params[1];
var popup = window.webkitNotifications.createNotification(icon, title, body);
popup.show();
setTimeout(function(){
popup.cancel();
}, '30');
}
}
*/

35
app/widgets/Poller/Poller.php

@ -0,0 +1,35 @@
<?php
/**
* @package Widgets
*
* @file Chat.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Poller extends WidgetBase
{
function WidgetLoad()
{
// We add the javascript that does the job.
$this->addjs('poller.js');
// And that's it!
}
function build()
{
}
}
?>

70
app/widgets/Poller/poller.js

@ -0,0 +1,70 @@
var empty_count = 0;
/**
* Attach a callback function to an event.
*/
function movimRegisterPollHandler(type, func)
{
if(!(type in movimPollHandlers)) {
movimPollHandlers[type] = new Array();
}
movimPollHandlers[type].push(func);
}
/**
* Polls the server.
*/
function movim_poll()
{
poller = rpc.make_xmlhttp();
poller.open('GET', BASE_URI+'jajax.php?do=poll', true);
poller.onreadystatechange = function()
{
if(poller.readyState == 4)
{
if(poller.status == 200) {
// Handling poll return.
if(poller.response == null) {
if(empty_count == 3)
movim_disconnect('&err=session');
else
empty_count++;
} else {
empty_count = 0;
rpc.handle_rpc_json(poller.response);
}
} else if(poller.status == 500 || poller.status == 400) {
movim_disconnect('&err=internal');
}
if(poller.status == 200) {
// Restarting polling.
movim_poll();
}
}
};
poller.send();
}
function movim_disconnect(error)
{
var url = window.location.href;
var urlparts = url.split('/');
var txt = urlparts[0]+'//';
for(i = 2; i < urlparts.length-1; i++) {
txt = txt+urlparts[i]+'/'
}
window.location.replace(txt+'index.php?q=disconnect' + error);
}
function halt_poll()
{
poller.abort();
}
// Adding the polling to onload event.
movim_add_onload(movim_poll);

144
app/widgets/Profile/Profile.php

@ -0,0 +1,144 @@
<?php
/**
* @package Widgets
*
* @file Profile.php
* This file is part of MOVIM.
*
* @brief The Profile widget
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Profile extends WidgetCommon
{
private static $status;
function WidgetLoad()
{
$this->addcss('profile.css');
$this->addjs('profile.js');
$this->registerEvent('myvcard', 'onMyVcardReceived');
$this->registerEvent('mypresence', 'onMyPresence');
}
function onMyVcardReceived($vcard = false)
{
$html = $this->prepareVcard($vcard);
RPC::call('movim_fill', 'profile', $html);
}
function onMyPresence()
{
RPC::call('movim_fill', 'statussaved', '✔ '.t('Saved'));
Notification::appendNotification(t('Status updated'), 'success');
}
function ajaxSetStatus($status)
{
$status = htmlspecialchars(rawurldecode($status));
// We update the cache with our status and presence
$presence = Cache::c('presence');
Cache::c(
'presence',
array(
'status' => $status,
'show' => $presence['show'],
)
);
switch($presence['show']) {
case 'chat':
$p = new moxl\PresenceChat();
$p->setStatus($status)->request();
break;
case 'away':
$p = new moxl\PresenceAway();
$p->setStatus($status)->request();
break;
case 'dnd':
$p = new moxl\PresenceDND();
$p->setStatus($status)->request();
break;
case 'xa':
$p = new moxl\PresenceXA();
$p->setStatus($status)->request();
break;
default :
$p = new moxl\PresenceChat();
$p->setStatus($status)->request();
break;
}
}
function prepareVcard($vcard = false)
{
$cd = new modl\ContactDAO();
$contact = $cd->get($this->user->getLogin());
$presence = Cache::c('presence');
if(isset($contact)) {
$me = $contact;
// My avatar
$html .= '
<a href="'.Route::urlize('friend',$this->user->getLogin()).'">
<img src="'.$me->getPhoto('l').'"/>
</a>';
// Contact general infos
$html .= '
<h1 style="text-decoration: none;">'.$me->getTrueName().'</h1>';
if($this->testIsSet($me->name))
$html .= $me->name.' ';
else
$html .= $me->getTrueName().' ';
if($this->testIsSet($me->url))
$html .= '<br /><a target="_blank" href="'.$me->url.'">'.$me->url.'</a>';
$html .= '
<div class="textbubble">
<textarea
id="status"
spellcheck="false"
onfocus="this.style.fontStyle=\'italic\'; this.parentNode.querySelector(\'#statussaved\').innerHTML = \'\'"
onblur="this.style.fontStyle=\'normal\';"
onkeypress="if(event.keyCode == 13) {'.$this->genCallAjax('ajaxSetStatus', 'encodeURIComponent(this.value)').'; this.blur(); return false;}"
onload="movim_textarea_autoheight(this);"
onkeyup="movim_textarea_autoheight(this);">'.$presence['status'].'</textarea>
<div id="statussaved" style="text-align: right;"></div>
</div>
';
} else {
$html .= '
'.t('No profile yet ?').'<br /><br />
<a class="button icon add" style="text-shadow: none; color: rgb(43, 43, 43); text-decoration: none;" href="?q=profile">'.t("Create my vCard").'</a><br /><br />';
}
return $html;
}
function build()
{
?>
<div id="profile">
<?php
echo $this->prepareVcard();
?>
</div>
<?php
}
}

47
app/widgets/Profile/profile.css

@ -0,0 +1,47 @@
#profile {
background-color: #272727;
margin: -1em;
padding: 1em;
line-height: 1.5em;
}
#profile h1 {
color: white;
line-height: 1.5em;
padding: 0px;
margin: 0.5em 0em;
}
#profile img {
width: auto;
height: auto;
display: block;
margin: -1em;
margin-bottom: 1em;
}
#profile .textbubble {
margin: -1em;
margin-top: 1em;
background-color: #171717;
padding: 1em;
}
#profile .textbubble textarea {
background-color: transparent;
border: 1px solid transparent;
font-size: 0.9em;
width: 100%;
resize: none;
color: white;
text-align: center;
padding: 0px;
}
#profile .textbubble textarea:hover {
border-color: white;
}
#profile textarea#status {
overflow: hidden;
}

13
app/widgets/Profile/profile.js

@ -0,0 +1,13 @@
function showPresence(n)
{
n.style.display = 'none';
buttons = document.querySelectorAll('.presence_button.merged');
for(i = 0; i < buttons.length; i++) {
buttons[i].style.display = 'inline';
}
}
movim_add_onload(function()
{
movim_textarea_autoheight(document.querySelector('#profile #status'));
});

123
app/widgets/ProfileData/ProfileData.php

@ -0,0 +1,123 @@
<?php
/**
* @package Widgets
*
* @file Profile.php
* This file is part of MOVIM.
*
* @brief The Profile widget
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ProfileData extends WidgetBase
{
function WidgetLoad()
{
$this->addjs('profiledata.js');
$this->registerEvent('locationpublished', 'onLocationPublished');
$this->registerEvent('locationpublisherror', 'onLocationPublishError');
}
function ajaxLocationPublish($pos)
{
$pos = json_decode($pos);
if($pos->place_id) {
$geo = array(
'latitude' => (string)$pos->lat,
'longitude' => (string)$pos->lon,
'altitude' => (string)$pos->alt,
'country' => (string)$pos->address->country,
'countrycode' => (string)$pos->address->country_code,
'region' => (string)$pos->address->county,
'postalcode' => (string)$pos->address->postcode,
'locality' => (string)$pos->address->city,
'street' => (string)$pos->address->path,
'building' => (string)$pos->address->building,
'text' => (string)$pos->display_name,
'uri' => ''//'http://www.openstreetmap.org/'.urlencode('?lat='.(string)$pos->lat.'&lon='.(string)$pos->lon.'&zoom=10')
);
$p = new moxl\LocationPublish();
$p->setTo($this->user->getLogin())
->setGeo($geo)
->request();
} else {
Notification::appendNotification(t('Wrong position'), 'error');
}
}
function onLocationPublished($me)
{
$html = $me->getPlace();
RPC::call('movim_fill', 'mapdata', $html);
Notification::appendNotification(t('Location updated'), 'success');
RPC::call('movim_delete', 'mapdiv');
RPC::commit();
}
function onLocationPublishError($error)
{
Notification::appendNotification($error, 'error');
RPC::call('movim_delete', 'mapdiv');
RPC::call('movim_delete', 'mapdata');
RPC::commit();
}
function prepareProfileData()
{
$submit = $this->genCallAjax('ajaxLocationPublish', "getMyPositionData()");
$cd = new modl\ContactDAO();
$c = $cd->get($this->user->getLogin());
if($c->loctimestamp) {
$data = prepareDate(strtotime($c->loctimestamp)).'<br /><br />';
$data .= $c->getPlace();
} else {
$data = '';
}
$html = '';
$html .= '
<h2>'.t('Location').'</h2>
<div id="location">
<div id="mapdata" style="margin-bottom: 10px;">'.$data.'</div>
<div id="mapdiv" style="width: auto; height: 250px; display: none;"></div>
<div class="clear"></div>
<a
class="button color green icon geo"
style="margin-top: 1em; display: block;"
onclick="getMyPosition(); this.style.display = \'none\';">'.
t('Update my position').'
</a>
<a
id="mypossubmit"
style="display: none;"
class="button color green icon yes"
onclick="'.$submit.' hidePositionChoice();">'.t('Accept').'</a><a
style="display: none; margin-top: 1em;"
id="myposrefuse"
onclick="hidePositionChoice();"
class="button tiny icon alone no merged right"></a>
</div>';
return $html;
}
function build()
{
echo $this->prepareProfileData();
}
}

61
app/widgets/ProfileData/profiledata.js

@ -0,0 +1,61 @@
var myposition = 0;
function getMyPositionData() { return myposition; }
window.cb = function cb(json) {
document.getElementById('mapdata').innerHTML = json.display_name + ',' + json.address.city;
myposition = JSON.stringify(json);
}
function hidePositionChoice()
{
document.querySelector("#mypossubmit").style.display = 'none';
document.querySelector("#myposrefuse").style.display = 'none';
}
function getMyPosition() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
document.querySelector("#mapdiv").style.display = 'block';
var map = L.map("mapdiv").setView([position.coords.latitude ,position.coords.longitude], 11);
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "",
maxZoom: 18
}).addTo(map);
var marker = L.marker([position.coords.latitude ,position.coords.longitude]).addTo(map)
var s = document.createElement('script');
s.src = 'http://nominatim.openstreetmap.org/reverse?json_callback=cb&format=json&lat='+position.coords.latitude+'&lon='+position.coords.longitude+'&zoom=27&addressdetails=1';
document.getElementsByTagName('head')[0].appendChild(s);
document.querySelector("#mypossubmit").style.display = 'block';
},
// next function is the error callback
function (error)
{
switch(error.code)
{
case error.TIMEOUT:
alert ('Timeout');
break;
case error.POSITION_UNAVAILABLE:
alert ('Position unavailable');
break;
case error.PERMISSION_DENIED:
alert ('Permission denied');
break;
case error.UNKNOWN_ERROR:
alert ('Unknown error');
break;
}
}
);
}
else {
}
}

83
app/widgets/PubsubSubscriptionConfig/PubsubSubscriptionConfig.php

@ -0,0 +1,83 @@
<?php
/**
* @package Widgets
*
* @file PubsubSubscriptionConfig.php
* This file is part of MOVIM.
*
* @brief The Group configuration widget
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 24 March 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class PubsubSubscriptionConfig extends WidgetBase
{
function WidgetLoad()
{
$this->registerEvent('groupsubscribedlist', 'onGroupSubscribedList');
$this->registerEvent('groupremoved', 'onGroupRemoved');
}
function prepareList($list) {
if(is_array($list[0])){
$html = '<ul class="list">';
foreach($list as $item){
$delete = $this->genCallAjax('ajaxDeleteFromGroupSubscribedList', "'".$item[0]."'", "'".$item[1]."'");
$html .= '
<li id="group'.$item[0].'">
<a class="action" onclick="'.$delete.'">'.t('Delete').'</a>
<a href="?q=node&s='.$item[1].'&n='.$item[0].'">'.$item[2].'</a>
</li>';
}
$html .= '</ul>';
return $html;
}
else return "No groups found";
}
function onGroupRemoved($node) {
RPC::call('movim_delete', 'group'.$node);
Notification::appendNotification(t('%s has been removed from your public groups', $node), 'success');
RPC::commit();
}
function onGroupSubscribedList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'listconfig', $html);
}
function ajaxDeleteFromGroupSubscribedList($node, $server){
$r = new moxl\PubsubSubscriptionListRemove();
$r->setNode($node)
->setTo($server)
->setFrom($this->user->getLogin())
->request();
}
function ajaxGetGroupSubscribedList(){
$r = new moxl\PubsubSubscriptionListGet();
$r->request();
}
function build()
{
?>
<div class="tabelem padded" title="<?php echo t('Public Groups'); ?>" id="groupsubscribedlistconfig">
<div id="listconfig">
<a class="button icon yes color green" onclick="<?php echo $this->genCallAjax('ajaxGetGroupSubscribedList'); ?>"><?php echo t("Get your public groups");?></a>
</div>
</div>
<?php
}
}
?>

402
app/widgets/Roster/Roster.php

@ -0,0 +1,402 @@
<?php
/**
* @package Widgets
*
* @file Roster.php
* This file is part of MOVIM.
*
* @brief The Roster widget
*
* @author Jaussoin Timothée <edhelas@gmail.com>
*
* @version 1.0
* @date 30 August 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class Roster extends WidgetBase
{
private $grouphtml;
function WidgetLoad()
{
$this->addcss('roster.css');
$this->addjs('roster.js');
$this->registerEvent('roster', 'onRoster');
$this->registerEvent('contactadd', 'onRoster');
$this->registerEvent('contactremove', 'onRoster');
$this->registerEvent('presence', 'onPresence');
$this->cached = false;
}
function onPresence($presence)
{
$arr = $presence->getPresence();
RPC::call('incomingPresence', $arr['jid'], $arr['presence_txt']);
}
function onRoster()
{
$html = $this->prepareRoster();
RPC::call('movim_fill', 'rosterlist', $html);
RPC::call('sortRoster');
}
/**
* @brief Force the roster refresh
* @returns
*
*
*/
function ajaxRefreshRoster()
{
$r = new moxl\RosterGetList();
$r->request();
}
/**
* @brief Generate the HTML for a roster contact
* @param $contact
* @param $inner
* @returns
*
*
*/
function prepareRosterElement($contact, $caps = false)
{
$html = '';
$html .= '<li
class="';
if($contact->jid == $_GET['f'])
$html .= 'active ';
if(isset($contact->last) && $contact->last > 60)
$html .= 'inactive ';
if(isset($contact->presence)) {
$presencestxt = getPresencesTxt();
$html.= $presencestxt[$contact->presence];
} else
$html .= 'offline';
$html .= '"';
$html .= '
id="roster'.$contact->jid.'"
>';
$type = '';
if($caps) {
foreach($caps as $c) {
if($c->node == $contact->node.'#'.$contact->ver) {
$type = $c->type;
}
}
}
$html .= '<div class="chat on" onclick="'.$this->genCallWidget("Chat","ajaxOpenTalk", "'".$contact->jid."'").'"></div>';
if($type == 'handheld')
$html .= '<div class="infoicon mobile"></div>';
if($type == 'web')
$html .= '<div class="infoicon web"></div>';
if($type == 'bot')
$html .= '<div class="infoicon bot"></div>';
if((isset($contact->tuneartist) && $contact->tuneartist != '') ||
(isset($contact->tunetitle) && $contact->tunetitle != ''))
$html .= '<div class="infoicon tune"></div>';
$html .= '<a
title="'.$contact->jid;
if($contact->status != '')
$html .= ' - '.htmlentities($contact->status);
if($contact->ressource != '')
$html .= ' ('.$contact->ressource.')';
$html .= '"';
$html .= ' href="'.Route::urlize('friend', $contact->jid).'"
>
<img
class="avatar"
src="'.$contact->getPhoto('s').'"
/>'.
$contact->getTrueName();
$html .= '<br /><span class="ressource">';
if($contact->rosterask == 'subscribe')
$html .= " #";
if($contact->ressource != '')
$html .= ' '.$contact->ressource.'';
$html .= '</span>
</a>';
$html .= '</li>';
return $html;
}
/**
* @brief Create the HTML for a roster group and add the title
* @param $contacts
* @param $i
* @returns html
*
*
*/
private function prepareRosterGroup($contacts, &$i, $caps)
{
$j = $i;
// We get the current name of the group
$currentgroup = $contacts[$i]->group;
// Temporary array to prevent duplicate contact
$duplicate = array();
// We grab all the contacts of the group
$grouphtml = '';
while(isset($contacts[$i]) && $contacts[$i]->group == $currentgroup) {
//if(!in_array($contacts[$i]->jid, $duplicate)) {
$grouphtml .= $this->prepareRosterElement($contacts[$i], $caps);
array_push($duplicate, $contacts[$i]->jid);
//}
$i++;
}
// And we add the title at the head of the group
if($currentgroup == '')
$currentgroup = t('Ungrouped');
$groupshown = '';
// get the current showing state of the group and the offline contacts
$groupState = Cache::c('group'.$currentgroup);
if($groupState == true)
$groupshown = 'groupshown';
$count = $i-$j;
$grouphtml = '
<div id="group'.$currentgroup.'" class="'.$groupshown.'">
<h1 onclick="'.$this->genCallAjax('ajaxToggleCache', "'group".$currentgroup."'").'">'.
$currentgroup.' - '.$count.'
</h1>'.$grouphtml.'
</div>';
return $grouphtml;
}
/**
* @brief Here we generate the roster
* @returns
*
*
*/
function prepareRoster()
{
$contactdao = new \modl\ContactDAO();
$contacts = $contactdao->getRoster();
$html = '';
$rd = new \modl\RosterLinkDAO();
$capsdao = new modl\CapsDAO();
$caps = $capsdao->getAll();
if(count($contacts) > 0) {
$i = 0;
while($i < count($contacts))
$html .= $this->prepareRosterGroup($contacts, $i, $caps);
} else {
$html .= '<script type="text/javascript">setTimeout(\''.$this->genCallAjax('ajaxRefreshRoster').'\', 1500);</script>';
}
return $html;
}
/**
* @brief Adding a new contact from the Rostermenu
* @param $jid
* @param $alias
* @returns
*
*
*/
function ajaxAddContact($jid, $alias) {
$r = new moxl\RosterAddItem();
$r->setTo($jid)
->request();
$p = new moxl\PresenceSubscribe();
$p->setTo($jid)
->request();
}
/**
* @brief Toggling boolean variables in the Cache
* @param $param
* @returns
*
*
*/
function ajaxToggleCache($param){
//$bool = !currentValue
$bool = (Cache::c($param) == true) ? false : true;
//toggling value in cache
Cache::c($param, $bool);
//$offline = new value of wether offline are shown or not
$offline = Cache::c('offlineshown');
if($param == 'offlineshown') {
RPC::call('showRoster', $bool);
} else
RPC::call('rosterToggleGroup', $param, $bool, $offline);
RPC::call('focusContact');
RPC::commit();
}
function ajaxToggleChat()
{
//$bool = !currentValue
$bool = (Cache::c('chatpop') == true) ? false : true;
//toggling value in cache
Cache::c('chatpop', $bool);
RPC::call('movim_fill', 'chattoggle', $this->prepareChatToggle());
RPC::commit();
}
function prepareChatToggle()
{
$chatpop = Cache::c('chatpop');
if($chatpop) {
$arrow = 'expand';
$ptoggle = 'openPopup();';
$call = $this->genCallAjax('ajaxToggleChat');
} else {
$arrow = 'contract';
$ptoggle = 'closePopup();';
$call = '';
}
$html = '
<li
onclick="'.$call.' '.$ptoggle.'"
title="'.t('Show/Hide').'">
<a class="'.$arrow.'" href="#"></a>
</li>';
return $html;
}
/**
* @brief Show/Hide the Roster
*/
function ajaxShowHideRoster() {
$bool = (Cache::c('rostershow') == true) ? false : true;
Cache::c('rostershow', $bool);
RPC::call('showHideRoster', $bool);
RPC::commit();
}
function build()
{
$offlineshown = '';
$offlineState = Cache::c('offlineshown');
$bool = Cache::c('rostershow');
if($bool)
$rostershow = 'hide';
if($offlineState == true)
$offlineshown = 'offlineshown';
?>
<div id="roster" class="<?php echo $rostershow; ?>">
<ul id="rosterlist" class="<?php echo $offlineshown; ?>">
<?php echo $this->prepareRoster(); ?>
</ul>
<script type="text/javascript">sortRoster();</script>
</div>
<div id="rostermenu" class="menubar">
<ul class="menu">
<li id="search">
<label class="search" for="rostershow"></label>
<input type="checkbox" id="rostershow"/>
<div class="tabbed">
<input
type="text"
name="search"
id="request"
autocomplete="off"
onkeyup="rosterSearch(event);"
onclick="focusContact();"
placeholder="<?php echo t('Search');?>"/>
</div>
</li>
<!--<li title="<?php echo t('Add'); ?>">
<label class="plus" for="addc"></label>
<input type="checkbox" id="addc"/>
<div class="tabbed">
<form id="addcontact">
<div class="element large mini">
<label for="addjid"><?php echo t('JID'); ?></label>
<input
id="addjid"
class="tiny"
placeholder="user@server.tld"
onfocus="myFocus(this);"
onblur="myBlur(this);"
/>
</div>
<a
class="button tiny icon no merged left black"
href="#"
id="addrefuse"
onclick="cancelAddJid();">
<?php echo t('Cancel'); ?>
</a><a
class="button tiny icon yes merged right black"
href="#"
id="addvalidate"
onclick="<?php $this->callAjax("ajaxAddContact", "getAddJid()", "getAddAlias()"); ?> cancelAddJid();">
<?php echo t('Send request'); ?>
</a>
</form>
</div>
</li>-->
<li
onclick="<?php echo $this->callAjax('ajaxToggleCache', "'offlineshown'");?>"
title="<?php echo t('Show/Hide'); ?>">
<a class="users" href="#"></a>
</li>
<div id="chattoggle">
<?php echo $this->prepareChatToggle(); ?>
</div>
<li
onclick="<?php echo $this->callAjax('ajaxShowHideRoster');?>"
title="<?php echo t('Show/Hide'); ?>">
<a class="down" href="#"></a>
</li>
</ul>
</div>
<?php
}
}
?>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save