From 882ecf654a38577d622236e3d52429d97cf1a104 Mon Sep 17 00:00:00 2001
From: src386
Date: Fri, 19 Feb 2016 14:14:25 +0100
Subject: [PATCH] update to movim upstream
---
CHANGELOG | 3 +
README.md | 2 +-
sources/CHANGELOG.md | 2 +
sources/app/controllers/BlogController.php | 1 +
sources/app/controllers/NodeController.php | 1 +
sources/app/helpers/StringHelper.php | 17 ++-
sources/app/models/message/Message.php | 20 ++-
sources/app/models/message/MessageDAO.php | 121 +++++++++++++-----
sources/app/models/postn/Postn.php | 7 +-
sources/app/models/postn/PostnDAO.php | 26 ++++
sources/app/views/adminlogin.tpl | 2 +-
sources/app/widgets/Blog/Blog.php | 2 +-
sources/app/widgets/Blog/blog.tpl | 2 +-
sources/app/widgets/Chat/Chat.php | 58 ++++++++-
sources/app/widgets/Chat/_chat.tpl | 4 +
sources/app/widgets/Chat/chat.js | 35 ++++-
sources/app/widgets/Chats/chats.css | 1 +
sources/app/widgets/Header/_header_about.tpl | 14 +-
sources/app/widgets/Header/_header_admin.tpl | 9 +-
.../app/widgets/Header/_header_adminlogin.tpl | 14 +-
.../app/widgets/Notification/notification.js | 36 +++---
sources/app/widgets/Post/Post.php | 3 +-
sources/app/widgets/Post/_post.tpl | 7 +-
sources/app/widgets/Post/_post_empty.tpl | 74 ++++++++++-
sources/app/widgets/Post/locales.ini | 2 +
sources/app/widgets/Roster/roster.css | 9 --
sources/composer.json | 3 +-
sources/linker.php | 3 +-
sources/system/controllers/AjaxController.php | 10 ++
sources/system/controllers/BaseController.php | 19 ++-
sources/system/template/TplPageBuilder.php | 1 -
sources/system/widget/WidgetBase.php | 24 ++--
sources/themes/material/css/color.css | 2 +-
sources/themes/material/css/header.css | 13 ++
sources/themes/material/css/listn.css | 11 +-
35 files changed, 444 insertions(+), 114 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 9928bca..e1b8501 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
**Changelog**
+1.7 ?
+- Update to movim 0.9 git2016-02-19
+
1.6.1 2016-02-12
- Update to movim 0.9 git2016-01-27
- Improve config/ and log/ protection (nginx)
diff --git a/README.md b/README.md
index 68a9846..8627c28 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Movim is a decentralized social network, written in PHP and HTML5 and based on t
It is recommended to use a "valid" certificate to use Movim, auto-signed is sometimes problematic. You might want to take a look a StartSSL or Let's Encrypt.
-Provided Movim version : 0.9 git2016-02-12
+Provided Movim version : 0.9 git2016-02-19
Please read CHANGELOG.
diff --git a/sources/CHANGELOG.md b/sources/CHANGELOG.md
index 8e776dc..96bb216 100644
--- a/sources/CHANGELOG.md
+++ b/sources/CHANGELOG.md
@@ -4,6 +4,8 @@ Movim Changelog
v0.9.1 (trunk)
---------------------------
* CSS fixes
+ * Add Last Message Edition support
+ * Improve Post discovery in the News page
v0.9
---------------------------
diff --git a/sources/app/controllers/BlogController.php b/sources/app/controllers/BlogController.php
index f2c6f1a..f009826 100644
--- a/sources/app/controllers/BlogController.php
+++ b/sources/app/controllers/BlogController.php
@@ -3,6 +3,7 @@
class BlogController extends BaseController {
function load() {
$this->session_only = false;
+ $this->public = true;
}
function dispatch() {
diff --git a/sources/app/controllers/NodeController.php b/sources/app/controllers/NodeController.php
index 6337538..d931e90 100644
--- a/sources/app/controllers/NodeController.php
+++ b/sources/app/controllers/NodeController.php
@@ -3,6 +3,7 @@
class NodeController extends BaseController {
function load() {
$this->session_only = false;
+ $this->public = true;
}
function dispatch() {
diff --git a/sources/app/helpers/StringHelper.php b/sources/app/helpers/StringHelper.php
index 29045ee..2d1f240 100644
--- a/sources/app/helpers/StringHelper.php
+++ b/sources/app/helpers/StringHelper.php
@@ -234,7 +234,11 @@ function explodeJid($jid)
if(isset($arr[1])) $resource = $arr[1];
else $resource = null;
- list($username, $server) = explode('@', $jid);
+ $server = '';
+
+ $arr = explode('@', $jid);
+ $username = $arr[0];
+ if(isset($arr[1])) $server = $arr[1];
return array(
'username' => $username,
@@ -373,3 +377,14 @@ function purifyHTML($string)
function firstLetterCapitalize($string) {
return ucfirst(strtolower(mb_substr($string, 0, 2)));
}
+
+/**
+ * Truncates the given string at the specified length.
+ *
+ * @param string $str The input string.
+ * @param int $width The number of chars at which the string will be truncated.
+ * @return string
+ */
+function truncate($str, $width) {
+ return strtok(wordwrap($str, $width, "…\n"), "\n");
+}
diff --git a/sources/app/models/message/Message.php b/sources/app/models/message/Message.php
index b4658e6..29cae40 100644
--- a/sources/app/models/message/Message.php
+++ b/sources/app/models/message/Message.php
@@ -3,6 +3,9 @@
namespace modl;
class Message extends Model {
+ public $id;
+ public $newid;
+
public $session;
public $jidto;
public $jidfrom;
@@ -21,6 +24,7 @@ class Message extends Model {
public $color; // Only for chatroom purpose
public $publishedPrepared; // Only for chat purpose
+ public $edited;
public function __construct()
{
@@ -28,6 +32,8 @@ class Message extends Model {
{
"session" :
{"type":"string", "size":128, "mandatory":true },
+ "id" :
+ {"type":"string", "size":36},
"jidto" :
{"type":"string", "size":128, "mandatory":true },
"jidfrom" :
@@ -47,7 +53,9 @@ class Message extends Model {
"published" :
{"type":"date"},
"delivered" :
- {"type":"date"}
+ {"type":"date"},
+ "edited" :
+ {"type":"int", "size":1}
}';
parent::__construct();
@@ -59,6 +67,10 @@ class Message extends Model {
$jid = explode('/',(string)$stanza->attributes()->from);
$to = current(explode('/',(string)$stanza->attributes()->to));
+ if(isset($stanza->attributes()->id)) {
+ $this->id = (string)$stanza->attributes()->id;
+ }
+
// This is not very beautiful
$user = new \User;
$this->session = $user->getLogin();
@@ -87,6 +99,12 @@ class Message extends Model {
// $this->html = \prepareString($this->body, false, $images);
//}
+ if($stanza->replace) {
+ $this->newid = $this->id;
+ $this->id = (string)$stanza->replace->attributes()->id;
+ $this->edited = true;
+ }
+
if($stanza->delay)
$this->published = gmdate('Y-m-d H:i:s', strtotime($stanza->delay->attributes()->stamp));
elseif($parent && $parent->delay)
diff --git a/sources/app/models/message/MessageDAO.php b/sources/app/models/message/MessageDAO.php
index f3af399..e76b75f 100644
--- a/sources/app/models/message/MessageDAO.php
+++ b/sources/app/models/message/MessageDAO.php
@@ -5,43 +5,27 @@ namespace modl;
class MessageDAO extends SQL {
function set(Message $message) {
$this->_sql = '
- insert into message
- (
- session,
- jidto,
- jidfrom,
- resource,
- type,
- subject,
- thread,
- body,
- html,
- published,
- delivered)
- values(
- :session,
- :jidto,
- :jidfrom,
- :resource,
- :type,
- :subject,
- :thread,
- :body,
- :html,
- :published,
- :delivered
- )';
+ update message
+ set id = :thread,
+ body = :body,
+ html = :html,
+ published = :published,
+ delivered = :delivered,
+ edited = 1
+
+ where session = :session
+ and id = :id
+ and jidto = :jidto
+ and jidfrom = :jidfrom';
$this->prepare(
'Message',
array(
+ 'thread' => $message->newid, // FIXME
+ 'id' => $message->id,
'session' => $message->session,
'jidto' => $message->jidto,
'jidfrom' => $message->jidfrom,
- 'resource' => $message->resource,
- 'type' => $message->type,
- 'subject' => $message->subject,
- 'thread' => $message->thread,
'body' => $message->body,
'html' => $message->html,
'published' => $message->published,
@@ -49,10 +33,85 @@ class MessageDAO extends SQL {
)
);
+ $this->run('Message');
+
+ if(!$this->_effective) {
+ $this->_sql = '
+ insert into message
+ (
+ id,
+ session,
+ jidto,
+ jidfrom,
+ resource,
+ type,
+ subject,
+ thread,
+ body,
+ html,
+ published,
+ delivered)
+ values(
+ :id,
+ :session,
+ :jidto,
+ :jidfrom,
+ :resource,
+ :type,
+ :subject,
+ :thread,
+ :body,
+ :html,
+ :published,
+ :delivered
+ )';
+
+ $this->prepare(
+ 'Message',
+ array(
+ 'id' => $message->id,
+ 'session' => $message->session,
+ 'jidto' => $message->jidto,
+ 'jidfrom' => $message->jidfrom,
+ 'resource' => $message->resource,
+ 'type' => $message->type,
+ 'subject' => $message->subject,
+ 'thread' => $message->thread,
+ 'body' => $message->body,
+ 'html' => $message->html,
+ 'published' => $message->published,
+ 'delivered' => $message->delivered
+ )
+ );
+ }
+
return $this->run('Message');
}
- function getContact($jid, $limitf = false, $limitr = false) {
+ function getLastItem($to)
+ {
+ $this->_sql = '
+ select * from message
+ where session = :session
+ and jidto = :jidto
+ and jidfrom = :jidfrom
+ order by published desc
+ limit 1';
+
+ $this->prepare(
+ 'Message',
+ array(
+ 'session' => $this->_user,
+ 'jidto' => $to,
+ 'jidfrom' => $this->_user
+ )
+ );
+
+ return $this->run('Message', 'item');
+ }
+
+ function getContact($jid, $limitf = false, $limitr = false)
+ {
$this->_sql = '
select * from message
where session = :session
diff --git a/sources/app/models/postn/Postn.php b/sources/app/models/postn/Postn.php
index 3806193..733e3a2 100644
--- a/sources/app/models/postn/Postn.php
+++ b/sources/app/models/postn/Postn.php
@@ -123,7 +123,8 @@ class Postn extends Model {
else
$entry = $item;
- $this->__set('origin', $from);
+ if($from != '')
+ $this->__set('origin', $from);
if($node)
$this->__set('node', $node);
@@ -358,9 +359,9 @@ class Postn extends Model {
public function getPublicUrl()
{
if($this->isMicroblog()) {
- return \Route::urlize('blog', array($this->origin));
+ return \Route::urlize('blog', array($this->origin, $this->nodeid));
} else {
- return \Route::urlize('node', array($this->origin, $this->node));
+ return \Route::urlize('node', array($this->origin, $this->node, $this->nodeid));
}
}
diff --git a/sources/app/models/postn/PostnDAO.php b/sources/app/models/postn/PostnDAO.php
index 60c21f3..acb2069 100644
--- a/sources/app/models/postn/PostnDAO.php
+++ b/sources/app/models/postn/PostnDAO.php
@@ -577,6 +577,32 @@ class PostnDAO extends SQL {
return $this->run('Postn');
}
+ function getLastBlogPublic($limitf = false, $limitr = false)
+ {
+ $this->_sql = '
+ select * from postn
+ left outer join contact on postn.aid = contact.jid
+ left outer join privacy on postn.nodeid = privacy.pkey
+ where
+ node = \'urn:xmpp:microblog:0\'
+ and postn.origin not in (select jid from rosterlink where session = :origin)
+ and privacy.value = 1
+ order by published desc
+ ';
+
+ if($limitr)
+ $this->_sql = $this->_sql.' limit '.$limitr.' offset '.$limitf;
+
+ $this->prepare(
+ 'Postn',
+ array(
+ 'origin' => $this->_user
+ )
+ );
+
+ return $this->run('ContactPostn');
+ }
+
function exist($id) {
$this->_sql = '
select count(*) from postn
diff --git a/sources/app/views/adminlogin.tpl b/sources/app/views/adminlogin.tpl
index 32aacd2..78c6e7f 100644
--- a/sources/app/views/adminlogin.tpl
+++ b/sources/app/views/adminlogin.tpl
@@ -1,5 +1,5 @@
- widget('Header'); ?>
+ widget('Header');?>
diff --git a/sources/app/widgets/Blog/Blog.php b/sources/app/widgets/Blog/Blog.php
index 8b2fc7f..654e3f8 100644
--- a/sources/app/widgets/Blog/Blog.php
+++ b/sources/app/widgets/Blog/Blog.php
@@ -67,7 +67,7 @@ class Blog extends WidgetBase {
$description = stripTags($this->_messages[0]->contentcleaned);
if(!empty($description)) {
- $this->description = $description;
+ $this->description = truncate($description, 100);
}
$attachements = $this->_messages[0]->getAttachements();
diff --git a/sources/app/widgets/Blog/blog.tpl b/sources/app/widgets/Blog/blog.tpl
index eb89315..5b15d9e 100644
--- a/sources/app/widgets/Blog/blog.tpl
+++ b/sources/app/widgets/Blog/blog.tpl
@@ -5,7 +5,7 @@
-
+
jidto = echapJid($to);
$m->jidfrom = $this->user->getLogin();
+ if($replace != false) {
+ $m->newid = Uuid::uuid4();
+ $m->id = $replace->id;
+ $m->edited = true;
+ $m->published = $replace->published;
+ $m->delivered = $replace->delivered;
+ } else {
+ $m->id = Uuid::uuid4();
+ $m->published = gmdate('Y-m-d H:i:s');
+ $m->delivered = gmdate('Y-m-d H:i:s');
+ }
+
$session = \Sessionx::start();
$m->type = 'chat';
@@ -250,10 +264,8 @@ class Chat extends WidgetBase
$m->jidfrom = $to;
}
- $m->body = rawurldecode($message);
+ $m->body = trim(rawurldecode($message));
//$m->html = prepareString($m->body, false, true);
- $m->published = gmdate('Y-m-d H:i:s');
- $m->delivered = gmdate('Y-m-d H:i:s');
if($resource != false) {
$to = $to . '/' . $resource;
@@ -265,6 +277,13 @@ class Chat extends WidgetBase
//$p->setHTML($m->html);
$p->setContent($m->body);
+ if($replace != false) {
+ $p->setId($m->newid);
+ $p->setReplace($m->id);
+ } else {
+ $p->setId($m->id);
+ }
+
if($muc) {
$p->setMuc();
}
@@ -284,6 +303,37 @@ class Chat extends WidgetBase
}
}
+ /**
+ * @brief Send a correction message
+ *
+ * @param string $to
+ * @param string $message
+ * @return void
+ */
+ function ajaxCorrect($to, $message)
+ {
+ $md = new \Modl\MessageDAO;
+ $m = $md->getLastItem($to);
+
+ if($m) {
+ $this->ajaxSendMessage($to, $message, false, false, $m);
+ }
+ }
+
+ /**
+ * @brief Get the last message sent
+ *
+ * @param string $to
+ * @return void
+ */
+ function ajaxLast($to)
+ {
+ $md = new \Modl\MessageDAO;
+ $m = $md->getLastItem($to);
+
+ RPC::call('Chat.setTextarea', $m->body);
+ }
+
/**
* @brief Send a "composing" message
*
diff --git a/sources/app/widgets/Chat/_chat.tpl b/sources/app/widgets/Chat/_chat.tpl
index 813e429..950d5c6 100644
--- a/sources/app/widgets/Chat/_chat.tpl
+++ b/sources/app/widgets/Chat/_chat.tpl
@@ -111,6 +111,10 @@
state = 0;
Chat.sendMessage(this.dataset.jid, {if="$muc"}true{else}false{/if});
return false;
+ } else if(event.keyCode == 38) {
+ Chat_ajaxLast(this.dataset.jid);
+ } else if(event.keyCode == 40) {
+ Chat.clearReplace();
} else {
{if="!$muc"}
if(state == 0 || state == 2) {
diff --git a/sources/app/widgets/Chat/chat.js b/sources/app/widgets/Chat/chat.js
index b6f607c..dfbc14c 100644
--- a/sources/app/widgets/Chat/chat.js
+++ b/sources/app/widgets/Chat/chat.js
@@ -5,6 +5,7 @@ var Chat = {
previous: null,
date: null,
lastScroll: null,
+ edit: false,
addSmiley: function(element) {
var n = document.querySelector('#chat_textarea');
n.value = n.value + element.dataset.emoji;
@@ -18,7 +19,12 @@ var Chat = {
n.value = "";
n.focus();
movim_textarea_autoheight(n);
- Chat_ajaxSendMessage(jid, encodeURIComponent(text), muc);
+ if(Chat.edit) {
+ Chat.edit = false;
+ Chat_ajaxCorrect(jid, encodeURIComponent(text));
+ } else {
+ Chat_ajaxSendMessage(jid, encodeURIComponent(text), muc);
+ }
},
focus: function()
{
@@ -26,8 +32,15 @@ var Chat = {
document.querySelector('#chat_textarea').focus();
}
},
- appendTextarea: function(value)
+ setTextarea: function(value)
{
+ Chat.edit = true;
+ document.querySelector('#chat_textarea').value = value;
+ },
+ clearReplace: function()
+ {
+ Chat.edit = false;
+ document.querySelector('#chat_textarea').value = '';
},
notify : function(title, body, image)
{
@@ -70,6 +83,7 @@ var Chat = {
for(var i = 0, len = messages.length; i < len; ++i ) {
Chat.appendMessage(messages[i], false);
}
+ Chat.edit = false;
}
},
appendMessage : function(message, prepend) {
@@ -127,6 +141,12 @@ var Chat = {
id = message.jidfrom + '_conversation';
}
+ if(message.id != null) {
+ bubble.id = message.id;
+ if(message.newid != null)
+ bubble.id = message.newid;
+ }
+
if(message.body.match(/^\/me/)) {
bubble.querySelector('div.bubble').className = 'bubble quote';
message.body = message.body.substr(4);
@@ -135,7 +155,12 @@ var Chat = {
if(bubble) {
bubble.querySelector('div.bubble > p').innerHTML = message.body.replace(/\r\n?|\n/g, '
');
- bubble.querySelector('div.bubble > span.info').innerHTML = message.publishedPrepared;
+ var info = bubble.querySelector('div.bubble > span.info');
+ info.innerHTML = message.publishedPrepared;
+
+ if(message.edited) {
+ info.innerHTML = ' ' + info.innerHTML;
+ }
if(prepend) {
Chat.date = message.published;
@@ -148,6 +173,10 @@ var Chat = {
var scrollDiff = discussion.scrollHeight - Chat.lastScroll;
discussion.scrollTop += scrollDiff;
Chat.lastScroll = discussion.scrollHeight;
+ } else if(message.edited) {
+ var elem = document.getElementById(message.id);
+ if(elem)
+ elem.parentElement.replaceChild(bubble, elem);
} else {
movim_append(id, bubble.outerHTML);
}
diff --git a/sources/app/widgets/Chats/chats.css b/sources/app/widgets/Chats/chats.css
index e146205..d028e62 100644
--- a/sources/app/widgets/Chats/chats.css
+++ b/sources/app/widgets/Chats/chats.css
@@ -5,3 +5,4 @@
#chats_widget_list:empty ~ .placeholder {
display: block;
}
+
diff --git a/sources/app/widgets/Header/_header_about.tpl b/sources/app/widgets/Header/_header_about.tpl
index b404cf8..f0b4a56 100644
--- a/sources/app/widgets/Header/_header_about.tpl
+++ b/sources/app/widgets/Header/_header_about.tpl
@@ -1,6 +1,12 @@
-
-
-
-
{$c->__('page.about')}
+
+ -
+
+
+
+
+
+
{$c->__('page.about')}
+
+
diff --git a/sources/app/widgets/Header/_header_admin.tpl b/sources/app/widgets/Header/_header_admin.tpl
index b0be03a..72ae085 100644
--- a/sources/app/widgets/Header/_header_admin.tpl
+++ b/sources/app/widgets/Header/_header_admin.tpl
@@ -1,9 +1,12 @@
diff --git a/sources/app/widgets/Header/_header_adminlogin.tpl b/sources/app/widgets/Header/_header_adminlogin.tpl
index 82e595a..72ae085 100644
--- a/sources/app/widgets/Header/_header_adminlogin.tpl
+++ b/sources/app/widgets/Header/_header_adminlogin.tpl
@@ -1,6 +1,12 @@
-
-
-
-
{$c->__('page.administration')}
+
diff --git a/sources/app/widgets/Notification/notification.js b/sources/app/widgets/Notification/notification.js
index 7e73444..f341a09 100644
--- a/sources/app/widgets/Notification/notification.js
+++ b/sources/app/widgets/Notification/notification.js
@@ -144,25 +144,27 @@ var Notification = {
Notification.document_title_init = document.title;
-MovimWebsocket.attach(function() {
- if(typeof Favico != 'undefined') {
- Notification.favicon = new Favico({
- animation: 'none',
- fontStyle: 'normal',
- bgColor: '#FF5722'
- });
- }
+if(typeof MovimWebsocket != 'undefined') {
+ MovimWebsocket.attach(function() {
+ if(typeof Favico != 'undefined') {
+ Notification.favicon = new Favico({
+ animation: 'none',
+ fontStyle: 'normal',
+ bgColor: '#FF5722'
+ });
+ }
- if(typeof require !== 'undefined') {
- var remote = require('remote');
- Notification.electron = remote.getCurrentWindow();
- }
+ if(typeof require !== 'undefined') {
+ var remote = require('remote');
+ Notification.electron = remote.getCurrentWindow();
+ }
- Notification.document_title = Notification.document_title_init;
- Notification.tab_counter1 = Notification.tab_counter2 = 0;
- Notification_ajaxGet();
- Notification.current(Notification.notifs_key);
-});
+ Notification.document_title = Notification.document_title_init;
+ Notification.tab_counter1 = Notification.tab_counter2 = 0;
+ Notification_ajaxGet();
+ Notification.current(Notification.notifs_key);
+ });
+}
document.onblur = function() {
Notification.focused = false;
diff --git a/sources/app/widgets/Post/Post.php b/sources/app/widgets/Post/Post.php
index be41545..3545cf7 100644
--- a/sources/app/widgets/Post/Post.php
+++ b/sources/app/widgets/Post/Post.php
@@ -165,7 +165,8 @@ class Post extends WidgetBase
$nd = new \modl\PostnDAO();
$view = $this->tpl();
- $view->assign('posts', $nd->getLastPublished(0, 10));
+ $view->assign('blogs', $nd->getLastBlogPublic(0, 6));
+ $view->assign('posts', $nd->getLastPublished(0, 4));
return $view->draw('_post_empty', true);
}
diff --git a/sources/app/widgets/Post/_post.tpl b/sources/app/widgets/Post/_post.tpl
index a1b9cd0..8816470 100644
--- a/sources/app/widgets/Post/_post.tpl
+++ b/sources/app/widgets/Post/_post.tpl
@@ -38,7 +38,7 @@
{/if}
-
+
{/if}
{if="($public && $post->isPublic()) || !$public"}
@@ -239,8 +239,11 @@
+ {$c->__('post.public')}
+
+
- {$c->__('post.public')}
+ {$c->__('post.public_url')}
diff --git a/sources/app/widgets/Post/_post_empty.tpl b/sources/app/widgets/Post/_post_empty.tpl
index dd30c3f..f0c0c98 100644
--- a/sources/app/widgets/Post/_post_empty.tpl
+++ b/sources/app/widgets/Post/_post_empty.tpl
@@ -1,6 +1,74 @@
-
-{$c->__('post.hot')}
-{$c->__('post.hot_text')}
+
+
+ -
+
+ {$c->__('post.hot')}
+
+
+ -
+
+
+
+
+
{$c->__('post.blog_last')}
+
+
+
+
+
+{loop="$blogs"}
+ {$attachements = $value->getAttachements()}
+ -
+ {$picture = $value->getPicture()}
+ {if="$picture != null"}
+
+ {else}
+ {$url = $value->getContact()->getPhoto('l')}
+ {if="$url"}
+
+
+ {else}
+
+
+
+ {/if}
+ {/if}
+
+ {if="isset($value->title)"}
+ {$value->title}
+ {else}
+ {$value->node}
+ {/if}
+
+
+
+ {$value->getContact()->getTrueName()}
+ –
+ {$value->published|strtotime|prepareDate}
+ {if="$value->published != $value->updated"}{/if}
+
+
+
+ {$value->contentcleaned|strip_tags}
+
+
+{/loop}
+
+
+
+ -
+
+
+
+
+
{$c->__('post.hot_text')}
+
+
+
{loop="$posts"}
{if="!filter_var($value->origin, FILTER_VALIDATE_EMAIL)"}
diff --git a/sources/app/widgets/Post/locales.ini b/sources/app/widgets/Post/locales.ini
index 45d5564..59dc740 100644
--- a/sources/app/widgets/Post/locales.ini
+++ b/sources/app/widgets/Post/locales.ini
@@ -9,10 +9,12 @@ hot_text = Posts recently published in Groups that you are not subscribed
new = New post
repost = This is a re-post from %s
repost_profile = See %s profile
+blog_last = Public posts from users
public = Publish this post publicly?
public_yes = This post is now public
public_no = This post is now private
+public_url = Public URL of this post
delete_title = Delete this post
delete_text = You are going to delete this post, please confirm your action
diff --git a/sources/app/widgets/Roster/roster.css b/sources/app/widgets/Roster/roster.css
index 00adfd1..bec81e1 100644
--- a/sources/app/widgets/Roster/roster.css
+++ b/sources/app/widgets/Roster/roster.css
@@ -1,12 +1,3 @@
-#roster form div {
- min-height: 0;
- top: 0;
-}
-
-#roster form div input {
- padding-top: 2rem;
-}
-
#roster ul#rosterlist > div > li {
min-height: 0;
}
diff --git a/sources/composer.json b/sources/composer.json
index 80d1309..98a7c8c 100644
--- a/sources/composer.json
+++ b/sources/composer.json
@@ -23,6 +23,7 @@
"forxer/Gravatar": "~1.2",
"respect/validation": "1.0.*",
- "ezyang/htmlpurifier": "^4.7"
+ "ezyang/htmlpurifier": "^4.7",
+ "ramsey/uuid": "^3.2"
}
}
diff --git a/sources/linker.php b/sources/linker.php
index 6be4369..039c45a 100644
--- a/sources/linker.php
+++ b/sources/linker.php
@@ -62,7 +62,8 @@ $stdin_behaviour = function ($data) use (&$conn, $loop, &$buffer, &$connector, &
} elseif($msg->func == 'unregister') {
\Moxl\Stanza\Stream::end();
} elseif($msg->func == 'register') {
- if(is_resource($conn->stream)) {
+ if(isset($conn)
+ && is_resource($conn->stream)) {
$conn->stream->close();
}
diff --git a/sources/system/controllers/AjaxController.php b/sources/system/controllers/AjaxController.php
index ba9e76f..46e590a 100644
--- a/sources/system/controllers/AjaxController.php
+++ b/sources/system/controllers/AjaxController.php
@@ -15,6 +15,7 @@ class AjaxController extends BaseController
{
protected $funclist = array();
protected static $instance;
+ protected $widgetlist = array();
public function __construct()
{
@@ -49,11 +50,20 @@ class AjaxController extends BaseController
return $buffer . "\n";
}
+ /**
+ * Check if the widget is registered
+ */
+ public function isRegistered($widget)
+ {
+ return array_key_exists($widget, $this->widgetlist);
+ }
+
/**
* Defines a new function.
*/
public function defun($widget, $funcname, array $params)
{
+ array_push($this->widgetlist, $widget);
$this->funclist[$widget.$funcname] = array(
'object' => $widget,
'funcname' => $funcname,
diff --git a/sources/system/controllers/BaseController.php b/sources/system/controllers/BaseController.php
index 2f42b3b..84c80ba 100644
--- a/sources/system/controllers/BaseController.php
+++ b/sources/system/controllers/BaseController.php
@@ -4,17 +4,11 @@ class BaseController {
public $name = 'main'; // The name of the current page
protected $session_only = false;// The page is protected by a session ?
protected $raw = false; // Display only the content ?
+ protected $public = false; // It's a public page
protected $page;
function __construct() {
$this->page = new TplPageBuilder();
- $this->page->addScript('movim_hash.js');
- $this->page->addScript('movim_utils.js');
- $this->page->addScript('movim_base.js');
- $this->page->addScript('movim_tpl.js');
- $this->page->addScript('movim_websocket.js');
- $this->page->addScript('movim_map.js');
- $this->page->addScript('pako_inflate.js');
}
/**
@@ -63,6 +57,17 @@ class BaseController {
}
function display() {
+ $this->page->addScript('movim_hash.js');
+ $this->page->addScript('movim_utils.js');
+ $this->page->addScript('movim_base.js');
+
+ if(!$this->public) {
+ $this->page->addScript('movim_tpl.js');
+ $this->page->addScript('movim_websocket.js');
+ $this->page->addScript('movim_map.js');
+ $this->page->addScript('pako_inflate.js');
+ }
+
if($this->session_only) {
$user = new User();
$content = new TplPageBuilder($user);
diff --git a/sources/system/template/TplPageBuilder.php b/sources/system/template/TplPageBuilder.php
index c8690ec..f6f3263 100644
--- a/sources/system/template/TplPageBuilder.php
+++ b/sources/system/template/TplPageBuilder.php
@@ -14,7 +14,6 @@ class TplPageBuilder
{
private $theme = 'movim';
private $_view = '';
- private $_color = 'green';
private $title = '';
private $menu = array();
private $content = '';
diff --git a/sources/system/widget/WidgetBase.php b/sources/system/widget/WidgetBase.php
index 3d79599..823a0e7 100644
--- a/sources/system/widget/WidgetBase.php
+++ b/sources/system/widget/WidgetBase.php
@@ -56,19 +56,21 @@ class WidgetBase
// Put default widget init here.
$this->ajax = AjaxController::getInstance();
- // Generating Ajax calls.
- $refl = new ReflectionClass($this->name);
- $meths = $refl->getMethods();
+ if(!$this->ajax->isRegistered($this->name)) {
+ // Generating Ajax calls.
+ $refl = new ReflectionClass($this->name);
+ $meths = $refl->getMethods();
- foreach($meths as $method) {
- if(preg_match('#^ajax#', $method->name)) {
- $pars = $method->getParameters();
- $params = array();
- foreach($pars as $param) {
- $params[] = $param->name;
+ foreach($meths as $method) {
+ if(preg_match('#^ajax#', $method->name)) {
+ $pars = $method->getParameters();
+ $params = array();
+ foreach($pars as $param) {
+ $params[] = $param->name;
+ }
+
+ $this->ajax->defun($this->name, $method->name, $params);
}
-
- $this->ajax->defun($this->name, $method->name, $params);
}
}
diff --git a/sources/themes/material/css/color.css b/sources/themes/material/css/color.css
index 1c383a6..33ec6d6 100644
--- a/sources/themes/material/css/color.css
+++ b/sources/themes/material/css/color.css
@@ -19,7 +19,7 @@
}
main > header a,
-.icon:not(.placeholder) a,
+.icon:not(.placeholder):not(.active) a,
.color input {
color: white;
}
diff --git a/sources/themes/material/css/header.css b/sources/themes/material/css/header.css
index e558606..99f3e61 100644
--- a/sources/themes/material/css/header.css
+++ b/sources/themes/material/css/header.css
@@ -27,3 +27,16 @@ header.fixed + div {
margin-top: 7rem;
}
+header ul:first-child > li:first-child {
+ text-align: center;
+}
+
+/* Specific forms in header */
+header form > div:not(.clear):not(.control) {
+ min-height: 0;
+ top: 0;
+}
+
+header form > div > input:not([type=submit]) {
+ padding-top: 2rem;
+}
diff --git a/sources/themes/material/css/listn.css b/sources/themes/material/css/listn.css
index bd96d3c..d09ccb9 100644
--- a/sources/themes/material/css/listn.css
+++ b/sources/themes/material/css/listn.css
@@ -68,6 +68,11 @@ ul.list li.subheader p {
padding-left: 2rem;
}
+ul.list li .primary > a,
+ul.list li .control > a {
+ display: block;
+}
+
/* Truncated content */
ul.list li.subheader > p,
@@ -276,8 +281,8 @@ ul li span.counter.bottom {
/* Bubble */
ul li div.bubble {
- padding: 1rem 2rem;
- border-radius: 0.25rem;
+ padding: 1.25rem 2rem 0.75rem;
+ border-radius: 0.5rem;
line-height: 2.75rem;
position: relative;
box-sizing: border-box;
@@ -303,6 +308,7 @@ ul li.oppose div.bubble {
margin-right: 9rem;
float: right;
position: initial;
+ background-color: #f5f5f5;
}
ul li div.bubble span.info {
@@ -341,6 +347,7 @@ ul li:not(.same) div.bubble:before {
ul li.oppose:not(.same) div.bubble:before {
left: calc(100% - 10.5rem);
top: 1.5rem;
+ border-top-color: #f5f5f5;
}
/* Icon */