Commit ae1c1666 authored by Dominik George's avatar Dominik George

New upstream version 0.14.1

parent ed56d73d
Movim Changelog
================
v0.14.1 (trunk)
v0.15 (trunk)
---------------------------
v0.14.1
---------------------------
* Replace ZeroMQ sockets with WebSockets, remove reactphp/zmq and php-zmq dependency
* Make Movim compatible with PHP 7.3
......@@ -24,6 +27,7 @@ v0.14.1 (trunk)
* Display single emojis as small stickers
* Display chat states in MUC, handle the chat states with a new ChatStates class
* Allow setting Avatars on Communities by combining XEP-0084 (metadata + url) and XEP-0060
* UI fixes for mobile (tabs)
v0.14
---------------------------
......
0.14.1rc5
0.14.1
\ No newline at end of file
......@@ -15,6 +15,11 @@ class Invite extends Model
return $this->belongsTo('App\User');
}
public function room()
{
return $this->hasOne('App\Contact', 'id', 'resource');
}
public static function set($jid, $resource)
{
$invitation = \App\Invite::where('user_id', $jid)
......
......@@ -85,7 +85,7 @@ var MovimWebsocket = {
if (obj.func == 'started') {
// If the linker was started but we're not on the login page
if (!['login', 'account', 'accountnext', 'tag', 'admin'].includes(MovimUtils.urlParts().page)) {
if (!['login', 'account', 'accountnext', 'tag', 'admin', 'about'].includes(MovimUtils.urlParts().page)) {
MovimUtils.disconnect();
} else {
MovimWebsocket.launchStarted();
......
var AdHoc = {
refresh: function() {
var items = document.querySelectorAll('#adhoc_widget li');
var items = document.querySelectorAll('#adhoc_widget li:not(.subheader)');
var i = 0;
while(i < items.length)
......
<div class="tabelem padded_top_bottom" title="{$c->__('page.avatar')}" id="avatar" >
<div class="tabelem padded_top_bottom" title="{$c->__('page.avatar')}" id="avatar">
<div id="avatar_form">
<ul class="list thick">
<li>
......
<div id="communities" class="tabelem spin" title="{$c->__('button.discover')}"></div>
<div id="communities" class="tabelem spin" title="{$c->__('button.discover')}" data-mobileicon="apps"></div>
......@@ -7,7 +7,7 @@
<label for="name">{$c->__('communitiesserver.name')}</label>
</div>
</section>
<div>
<div class="no_bar">
<button class="button flat" onclick="Dialog_ajaxClear()">
{$c->__('button.close')}
</button>
......
<div id="communities_servers" class="tabelem" title="{$c->__('communities.servers')}"></div>
<div id="communities_servers" class="tabelem" title="{$c->__('communities.servers')}" data-mobileicon="view_list"></div>
......@@ -11,7 +11,7 @@
<div>
<textarea id="pubsub#description" name="pubsub#description"
onkeyup="MovimUtils.textareaAutoheight(this);"
placeholder="{$c->__('communityconfig.description')}">{$config['pubsub#description']}</textarea>
placeholder="{$c->__('communityconfig.description')}">{if="isset($config['pubsub#description'])"}{$config['pubsub#description']}{/if}</textarea>
<label for="pubsub#description">{$c->__('communityconfig.description')}</label>
</div>
<div>
......
......@@ -17,7 +17,7 @@
</li>
</ul>
</section>
<div>
<div class="no_bar">
<button onclick="Dialog_ajaxClear()" class="button flat">
{$c->__('button.close')}
</button>
......
<div id="subscriptions" class="tabelem" title="{$c->__('communitysubscriptions.subscriptions')}">
<div id="subscriptions" class="tabelem" title="{$c->__('communitysubscriptions.subscriptions')}" data-mobileicon="bookmark">
{autoescape="off"}
{$c->prepareSubscriptions()}
{/autoescape}
......
......@@ -64,7 +64,7 @@ class ContactActions extends Base
$p->setTo((string)$form->searchjid->value)
->request();
Dialog::ajaxClear();
(new Dialog)->ajaxClear();
}
public function ajaxChat($jid)
......
......@@ -25,6 +25,18 @@
type="hidden"
value="{$contact->id}"
/>
<div>
<input
name="alias"
id="alias"
placeholder="{$c->__('edit.alias')}"
{if="$contact->name"}
value="{$contact->name}"
{else}
value="{$contact->truename}"
{/if}"/>
<label for="alias">{$c->__('edit.alias')}</label>
</div>
<div>
<datalist id="group_list" style="display: none;">
{if="is_array($groups)"}
......@@ -37,7 +49,6 @@
name="group"
list="group_list"
id="group"
class="tiny"
placeholder="{$c->__('edit.group')}"
value="{$contact->groupname}"/>
<label for="group">{$c->__('edit.group')}</label>
......
......@@ -58,12 +58,6 @@ class ContactData extends Base
}
}
public function ajaxAccept($jid)
{
$i = new Invitations;
$i->ajaxAccept($jid);
}
/**
* @brief Validate the jid
*
......
......@@ -106,19 +106,7 @@
{/if}
</li>
{/if}
<a href="{$c->route('blog', $contact->jid)}" target="_blank" class="block large simple">
<li>
<span class="primary icon">
<i class="material-icons">wifi_tethering</i>
</span>
<span class="control icon">
<i class="material-icons">chevron_right</i>
</span>
<p></p>
<p class="normal">{$c->__('blog.visit')}</p>
</li>
</a>
{if="$roster && $roster->subscription != 'both'"}
{if="$roster && !in_array($roster->subscription, ['', 'both'])"}
<li>
{if="$roster->subscription == 'to'"}
<span class="primary icon gray">
......@@ -127,7 +115,7 @@
<p>{$c->__('subscription.to')}</p>
<p>{$c->__('subscription.to_text')}</p>
<p>
<button class="button flat" onclick="ContactData_ajaxAccept('{$contact->id}')">
<button class="button flat" onclick="ContactActions_ajaxAddAsk('{$contact->id}')">
{$c->__('subscription.to_button')}
</button>
</p>
......@@ -139,7 +127,7 @@
<p>{$c->__('subscription.from')}</p>
<p>{$c->__('subscription.from_text')}</p>
<p>
<button class="button flat" onclick="ContactData_ajaxAccept('{$contact->id}')">
<button class="button flat" onclick="ContactActions_ajaxAddAsk('{$contact->id}')">
{$c->__('subscription.from_button')}
</button>
</p>
......@@ -152,13 +140,25 @@
<p>{$c->__('subscription.nil')}</p>
<p>{$c->__('subscription.nil_text')}</p>
<p>
<button class="button flat" onclick="ContactData_ajaxAccept('{$contact->id}')">
<button class="button flat" onclick="ContactActions_ajaxAddAsk('{$contact->id}')">
{$c->__('subscription.nil_button')}
</button>
</p>
{/if}
</li>
{/if}
<a href="{$c->route('blog', $contact->jid)}" target="_blank" class="block large simple">
<li>
<span class="primary icon">
<i class="material-icons">wifi_tethering</i>
</span>
<span class="control icon">
<i class="material-icons">chevron_right</i>
</span>
<p></p>
<p class="normal">{$c->__('blog.visit')}</p>
</li>
</a>
</ul>
</div>
......
......@@ -81,7 +81,7 @@ class ContactHeader extends Base
public function prepareHeader($jid)
{
$view = $this->tpl();
$view->assign('in_roster', ($this->user->session->contacts()->where('jid', $jid)->count() > 0));
$view->assign('roster', ($this->user->session->contacts()->where('jid', $jid)->first()));
$view->assign('contact', App\Contact::firstOrNew(['id' => $jid]));
return $view->draw('_contactheader');
......
<ul class="list thick">
<li class="">
{if="$in_roster"}
{if="$roster"}
<span class="control icon active gray" onclick="ContactHeader_ajaxEditContact('{$contact->id|echapJS}')"
title="{$c->__('button.edit')}">
<i class="material-icons">edit</i>
......@@ -31,8 +31,13 @@
<p class="line">
{$contact->truename}
{if="$roster && $roster->group"}
<span class="tag color {$roster->group|stringToColor}">{$roster->group}</span>
{/if}
</p>
<p class="line">
{$contact->id}
</p>
<p class="line">{$contact->id}</p>
</li>
{if="$contact->description != null && trim($contact->description) != ''"}
......
......@@ -5,12 +5,11 @@
<input
name="alias"
id="alias"
class="tiny"
placeholder="{$c->__('edit.alias')}"
{if="$contact->name"}
value="{$contact->name}"
{else}
value="{$contact->jid}"
value="{$contact->truename}"
{/if}"/>
<label for="alias">{$c->__('edit.alias')}</label>
</div>
......@@ -26,7 +25,6 @@
name="group"
list="group_list"
id="group"
class="tiny"
placeholder="{$c->__('edit.group')}"
value="{$contact->group}"/>
<label for="group">{$c->__('edit.group')}</label>
......@@ -34,7 +32,7 @@
<input type="hidden" name="jid" value="{$contact->jid}"/>
</form>
</section>
<div>
<div class="no_bar">
<button onclick="Dialog_ajaxClear()" class="button flat">
{$c->__('button.cancel')}
</button>
......
......@@ -15,8 +15,10 @@ class Help extends Base
public function display()
{
$this->view->assign('info',
\App\Info::where('server', $this->user->session->host)
->where('node', '')
->first());
($this->user->isLogged())
? \App\Info::where('server', $this->user->session->host)
->where('node', '')
->first()
: null);
}
}
......@@ -40,7 +40,7 @@
</p>
</li>
</ul>
{if="!empty($info->adminaddresses) || !empty($info->abuseaddresses) || !empty($info->supportaddresses) || !empty($info->securityaddresses)"}
{if="$info && (!empty($info->adminaddresses) || !empty($info->abuseaddresses) || !empty($info->supportaddresses) || !empty($info->securityaddresses))"}
<hr />
<ul class="list thin flex">
<li class="subheader block large">
......
......@@ -25,7 +25,8 @@ class Login extends Base
$this->registerEvent('storage_get_handle', 'onConfig');
$this->registerEvent('storage_get_errorfeaturenotimplemented', 'onConfig');
$this->registerEvent('storage_get_errorserviceunavailable', 'onConfig');
$this->registerEvent('ssl_error', 'onSSLError');
$this->registerEvent('ssl_error', 'onFailAuth');
$this->registerEvent('streamerror', 'onFailAuth');
}
public function onStart($packet)
......@@ -119,7 +120,7 @@ class Login extends Base
return $view->draw('_login_error');
}
public function onSSLError()
public function onFailAuth()
{
$this->showErrorBlock('fail_auth');
}
......
......@@ -83,9 +83,10 @@ body main {
color: gray;
}
ul.admin {
position: relative;
text-align: center;
color: white;
max-width: 45rem;
#login_widget ul.invite span.primary + span.primary {
left: 5rem;
}
#login_widget ul.invite span.primary + span.primary ~ p {
padding-left: 12rem;
}
\ No newline at end of file
......@@ -23,7 +23,7 @@
<h3>{$c->__('page.login')}</h3>
{if="$invitation != null"}
<br />
<ul class="list middle">
<ul class="list middle invite">
<li>
{$url = $contact->getPhoto('m')}
{if="$url"}
......@@ -34,8 +34,12 @@
{$contact->truename|firstLetterCapitalize}
</span>
{/if}
{if="$invitation->room && $invitation->room->getPhoto('m')"}
<span class="primary icon bubble" style="background-image: url({$invitation->room->getPhoto('m')});">
</span>
{/if}
<p></p>
<p class="all">{$c->__('form.invite_chatroom', $contact->truename)} - {$invitation->resource}</p>
<p class="all">{$c->__('form.invite_chatroom', $contact->truename)}: {$invitation->resource}</p>
</li>
</ul>
{/if}
......
......@@ -27,7 +27,7 @@ class Notifications extends Base
public function onPost($packet)
{
$post = $packet->content;
if ($post->isComment()) {
if ($post->isComment() && !$post->isMine()) {
$this->ajaxSetCounter();
}
}
......@@ -65,7 +65,8 @@ class Notifications extends Base
$query->select('id')
->from('posts')
->where('aid', $this->user->id);
})->where('published', '>', $since)->count();
})->where('published', '>', $since)
->where('aid', '!=', $this->user->id)->count();
$session = Session::start();
$notifs = $session->get('activenotifs');
......
......@@ -10,7 +10,7 @@
</div>
</form>
</section>
<div>
<div class="no_bar">
<button onclick="Dialog_ajaxClear();" class="button flat">
{$c->__('button.close')}
</button>
......
......@@ -91,7 +91,7 @@
</ul>
</div>
</section>
<div>
<div class="no_bar">
<button class="button flat" onclick="Dialog_ajaxClear()">
{$c->__('button.cancel')}
</button>
......
......@@ -26,7 +26,7 @@
<label>{$c->__('roster.add_contact_info1')}</label>
</div>
</section>
<div>
<div class="no_bar">
<button class="button flat" onclick="Dialog_ajaxClear()">
{$c->__('button.cancel')}
</button>
......
......@@ -50,7 +50,7 @@
</span>
{/if}
{if="$value->subscription != 'both'"}
{if="!in_array($value->subscription, ['', 'both'])"}
<span class="second">
{if="$value->subscription == 'to'"}
<i class="material-icons">arrow_upward</i>
......
......@@ -11,16 +11,43 @@ var Tabs = {
current = tabs[i].id;
}
html += '<li class="' + tabs[i].id + '" onclick="Tabs.change(this);">';
html += ' <a href="#" onclick="actDifferent(event);">' + tabs[i].title + '</a>';
html += '</li>';
var li = document.createElement('li');
li.setAttribute('class', tabs[i].id);
li.onclick = function() { Tabs.change(this) };
var a = document.createElement('a');
a.href = '#';
a.onclick = function(e) {
e.preventDefault();
return false;
};
if (tabs[i].dataset.mobileicon) {
aMobile = a.cloneNode(true);
a.classList.add('on_desktop');
aMobile.classList.add('on_mobile');
var icon = document.createElement('i');
icon.classList.add('material-icons');
icon.innerText = tabs[i].dataset.mobileicon;
aMobile.appendChild(icon);
li.appendChild(aMobile);
}
a.appendChild(document.createTextNode(tabs[i].title));
li.appendChild(a);
document.querySelector('#navtabs').appendChild(li);
}
// We show the first tab
tabs[0].classList.remove('hide');
// We insert the list
document.querySelector('#navtabs').innerHTML = html;
if (tabs.length == 3) {
document.querySelector('#navtabs').classList.add('wide');
}
if (current != null) {
tab = current;
......@@ -81,8 +108,3 @@ var Tabs = {
document.addEventListener("DOMContentLoaded", function(event) {
Tabs.create();
});
function actDifferent(e) {
e.preventDefault();
return false;
}
#upload img.preview_picture {
max-height: 25rem;
max-height: 35rem;
max-width: calc(100% - 4rem);
margin: 0 auto;
display: block;
}
#upload img.preview_picture[src] {
padding-bottom: 2rem;
}
#upload img.preview_picture[src] + li {
display: none;
}
\ No newline at end of file
......@@ -164,6 +164,8 @@ class Handler
'09ef1b34cf40fdd954f10d6e5075ee5c' => 'Carbons',
'201fa54dd93e3403611830213f5f9fbc' => 'Carbons',//?
'9a0cd265cabedadea095d8572d26167e' => 'StreamError',
'b95746de5ddc3fa5fbf28906c017d9d8' => 'STARTTLS',
'f728271d924a04b0355379b28c3183a1' => 'SASL',
......
<?php
namespace Moxl\Xec\Payload;
use Moxl\Stanza\Stream;
class StreamError extends Payload
{
public function handle($stanza, $parent = false)
{
$this->deliver();
}
}
......@@ -24,7 +24,8 @@
}
.dialog > section {
max-height: calc(90vh - 7.5rem);
max-height: calc(90vh - 7.2rem);
height: 100%;
overflow-y: auto;
position: relative;
}
......@@ -33,7 +34,7 @@
margin-top: 2rem;
}
.dialog > section > *:last-child {
.dialog > section > *:not(ul.list):last-child {
margin-bottom: 2rem;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment