diff --git a/app/helpers/DateHelper.php b/app/helpers/DateHelper.php
index 594fda4ac..db71e93c1 100755
--- a/app/helpers/DateHelper.php
+++ b/app/helpers/DateHelper.php
@@ -46,6 +46,8 @@ function getTimezoneCorrection() {
*/
function prepareDate($time, $hours = true) {
$t = $time ? $time : time();
+
+ $date = '';
$reldays = ((time() - $t)-(time()%86400))/86400;
// if $time is within a week
@@ -54,7 +56,7 @@ function prepareDate($time, $hours = true) {
if($reldays < -1) {
$date = __('date.tomorrow');
} else if ($reldays <= 0) {
- $date = __('date.today');
+ //$date = __('date.today');
} else if ($reldays <= 1) {
$date = __('date.yesterday');
}
@@ -71,8 +73,12 @@ function prepareDate($time, $hours = true) {
$date .= date(', Y', $t);
}
//if $hours option print the time
- if($hours)
- $date .= ' - '. date('H:i', $time);
+ if($hours) {
+ if($date != '') {
+ $date .= ' - ';
+ }
+ $date .= date('H:i', $time);
+ }
return $date;
}
diff --git a/app/helpers/StringHelper.php b/app/helpers/StringHelper.php
index 80edac208..c2a502a93 100755
--- a/app/helpers/StringHelper.php
+++ b/app/helpers/StringHelper.php
@@ -4,7 +4,51 @@ use HeyUpdate\Emoji\Emoji;
use HeyUpdate\Emoji\EmojiIndex;
/**
- * Prepare the string (add the a to the links and show the smileys)
+ * @desc A singleton wrapper for the Emoji library
+ */
+class MovimEmoji
+{
+ protected static $instance = null;
+ private $_emoji;
+ private $_theme;
+
+ protected function __construct()
+ {
+ $cd = new \Modl\ConfigDAO();
+ $config = $cd->get();
+ $this->_theme = $config->theme;
+
+ $this->_emoji = new Emoji(new EmojiIndex(), $this->getPath());
+ }
+
+ public function replace($string, $large = false)
+ {
+ $this->_emoji->setAssetUrlFormat($this->getPath($large));
+ $string = $this->_emoji->replaceEmojiWithImages($string);
+ $this->_emoji->setAssetUrlFormat($this->getPath());
+
+ return $string;
+ }
+
+ private function getPath($large = false)
+ {
+ $path = BASE_URI . 'themes/' . $this->_theme . '/img/emojis/';
+ if($large) $path .= 'large/';
+
+ return $path.'%s.png';
+ }
+
+ public static function getInstance()
+ {
+ if (!isset(static::$instance)) {
+ static::$instance = new MovimEmoji;
+ }
+ return static::$instance;
+ }
+}
+
+/**
+ * @desc Prepare the string (add the a to the links and show the smileys)
*
* @param string $string
* @return string
@@ -83,16 +127,8 @@ function prepareString($string, $large = false) {
);
// We add some smileys...
- $cd = new \Modl\ConfigDAO();
- $config = $cd->get();
- $theme = $config->theme;
-
- $path = BASE_URI . 'themes/' . $theme . '/img/emojis/';
-
- if($large) $path .= 'large/';
-
- $emoji = new Emoji(new EmojiIndex(), $path.'%s.png');
- $string = $emoji->replaceEmojiWithImages($string);
+ $emoji = MovimEmoji::getInstance();
+ $string = $emoji->replace($string, $large);
return trim($string);
}
diff --git a/app/models/message/Message.php b/app/models/message/Message.php
index 5748cdbe1..c74fe1e03 100755
--- a/app/models/message/Message.php
+++ b/app/models/message/Message.php
@@ -19,6 +19,8 @@ class Message extends Model {
public $published;
public $delivered;
+ public $color; // Only for chatroom purpose
+
public function __construct() {
$this->_struct = '
{
diff --git a/app/views/page.tpl b/app/views/page.tpl
index 5613786e7..d8903e0ab 100755
--- a/app/views/page.tpl
+++ b/app/views/page.tpl
@@ -19,8 +19,8 @@
+
-
addCss('color.css');
$this->addCss('block.css');
$this->addCss('menu.css');
+ $this->addCss('fonts.css');
$this->addCss('material-design-iconic-font.min.css');
$this->widget('System');
diff --git a/app/widgets/Chat/Chat.php b/app/widgets/Chat/Chat.php
index d45d026c0..252cbc234 100644
--- a/app/widgets/Chat/Chat.php
+++ b/app/widgets/Chat/Chat.php
@@ -18,7 +18,7 @@ class Chat extends WidgetCommon
$this->registerEvent('gone', 'onGone');
}
- function onMessage($packet)
+ function onMessage($packet, $mine = false)
{
$message = $packet->content;
$cd = new \Modl\ContactDAO;
@@ -50,7 +50,13 @@ class Chat extends WidgetCommon
$me = new \Modl\Contact;
}
- RPC::call('movim_append', $from.'_conversation', $this->prepareMessage($message, $from, $contact, $me));
+ if(preg_match('#^\?OTR#', $message->body)) {
+ if(!$mine) {
+ //RPC::call('ChatOTR.receiveMessage', $message->body);
+ }
+ } else {
+ RPC::call('Chat.appendMessage', $this->prepareMessage($message));
+ }
RPC::call('MovimTpl.scrollPanel');
}
@@ -121,6 +127,8 @@ class Chat extends WidgetCommon
RPC::call('movim_fill', 'chat_widget', $html);
RPC::call('MovimTpl.scrollPanel');
RPC::call('MovimTpl.showPanel');
+
+ $this->prepareMessages($jid);
}
}
@@ -138,6 +146,8 @@ class Chat extends WidgetCommon
RPC::call('movim_fill', 'chat_widget', $html);
RPC::call('MovimTpl.scrollPanel');
RPC::call('MovimTpl.showPanel');
+
+ $this->prepareMessages($room);
}
/**
@@ -170,9 +180,11 @@ class Chat extends WidgetCommon
$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);
+
+ if(!preg_match('#^\?OTR#', $m->body)) {
+ $md = new \Modl\MessageDAO();
+ $md->set($m);
+ }
/* Is it really clean ? */
$packet = new Moxl\Xec\Payload\Packet;
@@ -213,7 +225,7 @@ class Chat extends WidgetCommon
* @return void
*/
function ajaxSendPaused($to) {
- $mp=new Paused;
+ $mp = new Paused;
$mp->setTo($to)->request();
}
@@ -260,35 +272,16 @@ class Chat extends WidgetCommon
$view = $this->tpl();
$view->assign('jid', $jid);
- $view->assign('messages', $this->prepareMessages($jid));
$jid = echapJS($jid);
$view->assign('composing', $this->call('ajaxSendComposing', "'" . $jid . "'"));
$view->assign('paused', $this->call('ajaxSendPaused', "'" . $jid . "'"));
- $view->assign(
- 'send',
- $this->call(
- 'ajaxSendMessage',
- "'" . $jid . "'",
- "Chat.sendMessage('" . $jid . "')")
- );
$view->assign('smiley', $this->call('ajaxSmiley'));
$view->assign('emoji', prepareString('😀'));
-
- if($muc)
- {
- $view->assign(
- 'send',
- $this->call(
- 'ajaxSendMessage',
- "'" . $jid . "'",
- "Chat.sendMessage('" . $jid . "')",
- "true")
- );
- }
+ $view->assign('muc', $muc);
return $view->draw('_chat', true);
}
@@ -296,48 +289,53 @@ class Chat extends WidgetCommon
function prepareMessages($jid)
{
$md = new \Modl\MessageDAO();
- $messages = $md->getContact(echapJid($jid), 0, 15);
-
- $cd = new \Modl\ContactDAO;
+ $messages = $md->getContact(echapJid($jid), 0, 30);
+
+ $messages = array_reverse($messages);
+
+ foreach($messages as $message) {
+ $this->prepareMessage($message);
+ }
+
$view = $this->tpl();
+ $view->assign('jid', $jid);
+ $cd = new \Modl\ContactDAO;
$contact = $cd->get($jid);
$me = $cd->get();
if($me == null) {
$me = new \Modl\Contact;
- }
+ }
- $messages = array_reverse($messages);
+ $view->assign('contact', $contact);
+ $view->assign('me', false);
+ $left = $view->draw('_chat_bubble', true);
- $messages_html = '';
- foreach($messages as $m) {
- $messages_html .= $this->prepareMessage($m, $jid, $contact, $me);
- }
+ $view->assign('contact', $me);
+ $view->assign('me', true);
+ $right = $view->draw('_chat_bubble', true);
- $view->assign('jid', $jid);
- $view->assign('messages_html', $messages_html);
+ $room = $view->draw('_chat_bubble_room', true);
- return $view->draw('_chat_messages', true);
+ RPC::call('Chat.setBubbles', $left, $right, $room);
+ RPC::call('Chat.appendMessages', $messages);
}
- function prepareMessage($message, $jid, $contact, $me)
+ function prepareMessage(&$message)
{
- $view = $this->tpl();
-
- $view->assign('jid', $jid);
- $view->assign('contact', $contact);
- $view->assign('me', $me);
- $view->assign('message', $message);
+ if(isset($message->html)) {
+ $message->body = prepareString($message->html);
+ } else {
+ $message->body = prepareString(htmlentities($message->body , ENT_COMPAT,'UTF-8'));
+ }
if($message->type == 'groupchat') {
- $cd = new \Modl\ContactDAO;
- $contact = $cd->getPresence($jid, $message->resource);
- if(!$contact) $contact = new \Modl\Contact;
-
- $view->assign('contact', $contact);
+ $message->color = stringToColor($message->jidfrom.$message->resource);
}
- return $view->draw('_chat_message', true);
+ $message->published = prepareDate(strtotime($message->published));
+
+ return $message;
}
function prepareEmpty()
diff --git a/app/widgets/Chat/_chat.tpl b/app/widgets/Chat/_chat.tpl
index 136865208..9f3783611 100644
--- a/app/widgets/Chat/_chat.tpl
+++ b/app/widgets/Chat/_chat.tpl
@@ -1,6 +1,6 @@
@@ -21,25 +21,29 @@
onkeypress="
if(event.keyCode == 13) {
state = 0;
- {$send}
+ Chat.sendMessage('{$jid}', {if="$muc"}true{else}false{/if});
return false;
} else {
+ {if="!$muc"}
if(state == 0 || state == 2) {
state = 1;
{$composing}
since = new Date().getTime();
}
+ {/if}
}
"
onkeyup="
movim_textarea_autoheight(this);
+ {if="!$muc"}
setTimeout(function()
{
if(state == 1 && since+5000 < new Date().getTime()) {
state = 2;
{$paused}
}
- },5000);
+ },5000);
+ {/if}
"
placeholder="{$c->__('chat.placeholder')}"
>
diff --git a/app/widgets/Chat/_chat_bubble.tpl b/app/widgets/Chat/_chat_bubble.tpl
new file mode 100644
index 000000000..f1dd60085
--- /dev/null
+++ b/app/widgets/Chat/_chat_bubble.tpl
@@ -0,0 +1,17 @@
+
+ {$url = $contact->getPhoto('s')}
+ {if="$url"}
+
+
+
+ {else}
+
+
+
+ {/if}
+
+
+
diff --git a/app/widgets/Chat/_chat_bubble_room.tpl b/app/widgets/Chat/_chat_bubble_room.tpl
new file mode 100644
index 000000000..9783ff48c
--- /dev/null
+++ b/app/widgets/Chat/_chat_bubble_room.tpl
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/widgets/Chat/_chat_header.tpl b/app/widgets/Chat/_chat_header.tpl
index 71061614b..096acfc17 100644
--- a/app/widgets/Chat/_chat_header.tpl
+++ b/app/widgets/Chat/_chat_header.tpl
@@ -10,7 +10,7 @@
-
+
jidfrom != $jid"}class="oppose"{/if}>
- {if="$message->jidfrom == $jid"}
- {$url = $contact->getPhoto('s')}
- {if="$url"}
-
-
-
- {elseif="$message->type == 'groupchat'"}
-
-
-
- {else}
-
-
-
- {/if}
- {else}
-
-
-
- {/if}
-
- {if="preg_match('#^\/me#', $message->body)"}
- {$message->body = '* '.substr($message->body, 3)}
- {$class = 'quote'}
- {else}
- {$class = ''}
- {/if}
-
-
- {if="preg_match('#^\?OTR#', $message->body)"}
-
{$c->__('message.encrypted')}
-
- {else}
-
{if="isset($message->html)"}{$message->html|prepareString}{else}{$message->body|htmlentities:ENT_COMPAT,'UTF-8'|prepareString}{/if}
- {/if}
-
{$message->published|strtotime|prepareDate}
- {if="$message->type == 'groupchat'"}
-
{$message->resource} -
- {/if}
-
-
-{/if}
diff --git a/app/widgets/Chat/_chat_messages.tpl b/app/widgets/Chat/_chat_messages.tpl
deleted file mode 100644
index be95aba98..000000000
--- a/app/widgets/Chat/_chat_messages.tpl
+++ /dev/null
@@ -1,21 +0,0 @@
-
diff --git a/app/widgets/Chat/chat.css b/app/widgets/Chat/chat.css
index 60fce9ac3..88d531875 100644
--- a/app/widgets/Chat/chat.css
+++ b/app/widgets/Chat/chat.css
@@ -1,3 +1,12 @@
+#chat_header.encrypted:after{
+ content: "";
+ display: inline-block;
+ font-family: "Material Design Iconic Font";
+ content: "\f041";
+ font-size: 2.5rem;
+ margin-left: 1rem;
+}
+
#chat_widget .chat_box {
position: fixed;
bottom: 0;
@@ -45,6 +54,28 @@
margin: 0.2rem;
}
+/* Chatroom */
+
+#chat_widget li.room {
+ min-height: 3rem;
+ margin-bottom: 0.5rem;
+}
+#chat_widget li.room:first-child {
+ margin-top: 1rem;
+}
+
+#chat_widget li.room,
+#chat_widget li.room div,
+#chat_widget li.room span.user {
+ line-height: 3rem;
+}
+
+#chat_widget li.room span.user {
+ font-weight: 700;
+ float: left;
+ margin-right: 1rem;
+}
+
table.emojis td {
width: 10%;
text-align: center;
diff --git a/app/widgets/Chat/chat.js b/app/widgets/Chat/chat.js
index d390a890a..ca8074db6 100644
--- a/app/widgets/Chat/chat.js
+++ b/app/widgets/Chat/chat.js
@@ -1,17 +1,20 @@
var Chat = {
+ left : null,
+ right: null,
+ right: null,
addSmiley: function(element) {
var n = document.querySelector('#chat_textarea');
n.value = n.value + element.dataset.emoji;
n.focus();
Dialog.clear();
},
- sendMessage: function(jid)
+ sendMessage: function(jid, muc)
{
var n = document.querySelector('#chat_textarea');
var text = n.value;
n.value = "";
n.focus();
- return encodeURIComponent(text);
+ Chat_ajaxSendMessage(jid, encodeURIComponent(text), muc);
},
appendTextarea: function(value)
{
@@ -26,6 +29,61 @@ var Chat = {
empty : function()
{
Chat_ajaxGet();
+ },
+ setBubbles : function(left, right, room) {
+ var div = document.createElement('div');
+
+ div.innerHTML = left;
+ Chat.left = div.firstChild;
+ div.innerHTML = right;
+ Chat.right = div.firstChild;
+ div.innerHTML = room;
+ Chat.room = div.firstChild;
+ },
+ appendMessages : function(messages) {
+ for(var i = 0, len = messages.length; i < len; ++i ) {
+ Chat.appendMessage(messages[i]);
+ }
+ },
+ appendMessage : function(message) {
+ if(message.body == '') return;
+
+ var bubble = null;
+ var id = null;
+
+ if(message.type == 'groupchat') {
+ bubble = Chat.room;
+ id = message.jidfrom + '_conversation';
+ bubble.querySelector('div').innerHTML = message.body;
+ bubble.querySelector('span.info').innerHTML = message.published;
+ console.log(message.color);
+ bubble.querySelector('span.user').className = 'user ' + message.color;
+ bubble.querySelector('span.user').innerHTML = message.resource;
+ } else {
+ if(message.session == message.jidfrom) {
+ bubble = Chat.right;
+ id = message.jidto + '_conversation';
+ } else {
+ bubble = Chat.left;
+ id = message.jidfrom + '_conversation';
+ }
+
+ bubble.querySelector('div.bubble div').innerHTML = message.body;
+ bubble.querySelector('div.bubble span.info').innerHTML = message.published;
+ }
+
+ /*
+ bubble.querySelector('div.bubble div').innerHTML = message.body;
+ if(message.type == 'groupchat') {
+ bubble.querySelector('div.bubble div').innerHTML = '' + message.resource + ': ' + message.body;
+ bubble.querySelector('div.bubble').className = 'bubble room';
+ } else {
+
+ }*/
+
+ movim_append(id, bubble.outerHTML);
+
+ MovimTpl.scrollPanel();
}
}
diff --git a/app/widgets/Chat/chat_otr.js b/app/widgets/Chat/chat_otr.js
index 40f0efa00..59f92bba6 100644
--- a/app/widgets/Chat/chat_otr.js
+++ b/app/widgets/Chat/chat_otr.js
@@ -1,5 +1,6 @@
var ChatOTR = {
buddy : null,
+ status : 0,
load : function(jid) {
var key = ChatOTR.getKey();
@@ -12,23 +13,25 @@ var ChatOTR = {
ChatOTR.buddy = new OTR(options)
ChatOTR.buddy.on('ui', function (msg, encrypted, meta) {
- console.log("message to display to the user: " + msg)
- //if(encrypted) {
- var message = document.querySelector('.pending');
- message.innerHTML = msg;
- message.className = '';
+ console.log("!!! message to display to the user: " + msg)
- ChatOTR.cleanPending();
- //}
- // encrypted === true, if the received msg was encrypted
-
- //console.log("(optional) with receiveMsg attached meta data: " + meta)
+ var message = {
+ session : 'me',
+ jidfrom : 'demonstration@movim.eu',
+ jidto : 'me',
+ type : 'chat',
+ body : msg
+ };
+
+ console.log(message);
+
+ Chat.appendMessage(message);
});
ChatOTR.buddy.on('io', function (msg, meta) {
- console.log("message to send to buddy: " + msg)
- Chat_ajaxSendMessage('demonstration@movim.eu', msg);
- console.log("(optional) with sendMsg attached meta data: " + meta)
+ console.log(">>> message to send to buddy: " + msg)
+ Chat_ajaxSendMessage('demonstration@movim.eu', msg);
+ //console.log("(optional) with sendMsg attached meta data: " + meta)
});
ChatOTR.buddy.on('error', function (err, severity) {
@@ -36,23 +39,36 @@ var ChatOTR = {
console.error("error occurred: " + err)
});
- console.log(ChatOTR.buddy);
- },
+ ChatOTR.buddy.on('status', function (state) {
+ switch (state) {
+ case OTR.CONST.STATUS_AKE_SUCCESS:
+ movim_add_class(document.querySelector('#chat_header'), 'encrypted');
+ ChatOTR.status = 2;
+ break
+ case OTR.CONST.STATUS_END_OTR:
+ movim_remove_class(document.querySelector('#chat_header'), 'encrypted');
+ ChatOTR.status = 0;
+ break
+ }
+ });
- cleanPending : function() {
- var pending = document.querySelectorAll('.pending');
+ },
- var i = 0;
- while(i < pending.length)
- {
- pending[i].innerHTML = 'cant read';
- pending[i].className = '';
- i++;
+ receiveMessage : function(enc) {
+ console.log("<<< message received from the buddy: " + enc);
+ if(ChatOTR.status == 0) {
+ ChatOTR.buddy.sendQueryMsg();
+ ChatOTR.status = 1;
}
+ ChatOTR.buddy.receiveMsg(enc);
},
sendMessage : function(msg) {
- ChatOTR.buddy.sendMsg(msg);
+ if(ChatOTR.status == 0) {
+ Chat_ajaxSendMessage('demonstration@movim.eu', msg);
+ } else {
+ ChatOTR.buddy.sendMsg(msg);
+ }
},
getKey : function() {
@@ -64,25 +80,6 @@ var ChatOTR = {
var key = localStorage.getObject('otr_key');
return DSA(key);
- },
-
- clear : function() {
- document.getElementById('demonstration@movim.eu_conversation').innerHTML = '';
- },
-
- decryptAll : function() {
- ChatOTR.cleanPending();
-
- var encrypted = document.querySelectorAll('.encrypted');
-
- var i = 0;
- while(i < encrypted.length)
- {
- var enc = encrypted[i].innerHTML;
- encrypted[i].className = 'pending';
- ChatOTR.buddy.receiveMsg(enc);
- i++;
- }
}
}
diff --git a/app/widgets/Chats/chats.js b/app/widgets/Chats/chats.js
index b20d169b3..4a84e53f6 100644
--- a/app/widgets/Chats/chats.js
+++ b/app/widgets/Chats/chats.js
@@ -13,6 +13,8 @@ var Chats = {
Notification_ajaxClear('chat|' + this.dataset.jid);
Notification.current('chat|' + this.dataset.jid);
movim_add_class(this, 'active');
+
+ MovimTpl.scrollPanel();
}
items[i].onmousedown = function(e) {
diff --git a/app/widgets/Rooms/Rooms.php b/app/widgets/Rooms/Rooms.php
index b3fbde475..61f775351 100644
--- a/app/widgets/Rooms/Rooms.php
+++ b/app/widgets/Rooms/Rooms.php
@@ -67,7 +67,7 @@ class Rooms extends WidgetCommon
}
/**
- * @brief Display the remove room confirmation
+ * @brief Display the remove list
*/
function ajaxList($room)
{
diff --git a/linker.php b/linker.php
index 98463048a..ba71d19fc 100755
--- a/linker.php
+++ b/linker.php
@@ -45,7 +45,7 @@ $connector($config->websocketurl, array('xmpp'))->then(function($conn) use (&$st
$conn->on('message', function($message) use ($conn, $loop) {
if($message != '') {
- #fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n");
+ fwrite(STDERR, colorize($message, 'yellow')." : ".colorize('received', 'green')."\n");
if($message == '') {
$conn->close();
@@ -76,7 +76,7 @@ $connector($config->websocketurl, array('xmpp'))->then(function($conn) use (&$st
}
if(!empty($xml)) {
- #fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
+ fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
$conn->send(trim($xml));
}
}
@@ -118,7 +118,7 @@ $connector($config->websocketurl, array('xmpp'))->then(function($conn) use (&$st
\Moxl\API::clear();
if(!empty($xml)) {
- #fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
+ fwrite(STDERR, colorize(trim($xml), 'yellow')." : ".colorize('sent to XMPP', 'green')."\n");
$conn->send(trim($xml));
}
diff --git a/themes/material/css/color.css b/themes/material/css/color.css
index 07202c9ef..39754c947 100644
--- a/themes/material/css/color.css
+++ b/themes/material/css/color.css
@@ -71,15 +71,15 @@ span.icon.status.away:after,
.bubble.color.brown , .icon.color.brown { color: white; background-color: #795548; border-color: #795548 }
.bubble.color.gray , .icon.color.gray { color: white; background-color: #9E9E9E; border-color: #9E9E9E }
-label.red , .icon.red { color: #F44336; }
-label.purple, .icon.purple { color: #9C27B0; }
-label.indigo, .icon.indigo { color: #3F51B5; }
-label.blue , .icon.blue { color: #2196F3; }
-label.green , .icon.green { color: #689F38; }
-label.orange, .icon.orange { color: #FF9800; }
-label.yellow, .icon.yellow { color: #FFEB3B; }
-label.brown , .icon.brown { color: #795548; }
-label.gray , .icon.gray { color: #9E9E9E; }
+label.red , .icon.red , span.user.red { color: #F44336; }
+label.purple, .icon.purple, span.user.purple { color: #9C27B0; }
+label.indigo, .icon.indigo, span.user.indigo { color: #3F51B5; }
+label.blue , .icon.blue , span.user.blue { color: #2196F3; }
+label.green , .icon.green , span.user.green { color: #689F38; }
+label.orange, .icon.orange, span.user.orange { color: #FF9800; }
+label.yellow, .icon.yellow, span.user.yellow { color: #FFEB3B; }
+label.brown , .icon.brown , span.user.brown { color: #795548; }
+label.gray , .icon.gray , span.user.gray { color: #9E9E9E; }
form input:focus:invalid,
form textarea:focus:invalid {
diff --git a/themes/material/css/fonts.css b/themes/material/css/fonts.css
new file mode 100755
index 000000000..a42ad0130
--- /dev/null
+++ b/themes/material/css/fonts.css
@@ -0,0 +1,30 @@
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Open Sans Light'), local('OpenSans-Light'), url(../fonts/os_300.woff2) format('woff2'), url(../fonts/os_300.woff2) format('woff');
+}
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Open Sans'), local('OpenSans'), url(../fonts/os_400.woff2) format('woff2'), url(../fonts/os_400.woff) format('woff');
+}
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 600;
+ src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(../fonts/os_600.woff2) format('woff2'), url(../fonts/os_600.woff) format('woff');
+}
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Open Sans Bold'), local('OpenSans-Bold'), url(../fonts/os_700.woff2) format('woff2'), url(../fonts/os_700.woff) format('woff');
+}
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 800;
+ src: local('Open Sans Extrabold'), local('OpenSans-Extrabold'), url(../fonts/os_800.woff2) format('woff2'), url(../fonts/os_800.woff) format('woff');
+}
diff --git a/themes/material/css/style.css b/themes/material/css/style.css
index 5cf386821..1a3579a89 100644
--- a/themes/material/css/style.css
+++ b/themes/material/css/style.css
@@ -112,6 +112,9 @@ label, span.info { /* Caption */
font-size: 1.5rem;
color: rgba(0, 0, 0, 0.54);
}
+label, span.info b { /* Caption */
+ font-weight: 600;
+}
/* Navigation bar */
diff --git a/themes/material/fonts/os_300.woff b/themes/material/fonts/os_300.woff
new file mode 100644
index 000000000..70646281e
Binary files /dev/null and b/themes/material/fonts/os_300.woff differ
diff --git a/themes/material/fonts/os_300.woff2 b/themes/material/fonts/os_300.woff2
new file mode 100644
index 000000000..90b828fe4
Binary files /dev/null and b/themes/material/fonts/os_300.woff2 differ
diff --git a/themes/material/fonts/os_400.woff b/themes/material/fonts/os_400.woff
new file mode 100644
index 000000000..e9ce2f320
Binary files /dev/null and b/themes/material/fonts/os_400.woff differ
diff --git a/themes/material/fonts/os_400.woff2 b/themes/material/fonts/os_400.woff2
new file mode 100644
index 000000000..bf65567c2
Binary files /dev/null and b/themes/material/fonts/os_400.woff2 differ
diff --git a/themes/material/fonts/os_600.woff b/themes/material/fonts/os_600.woff
new file mode 100644
index 000000000..6304fc979
Binary files /dev/null and b/themes/material/fonts/os_600.woff differ
diff --git a/themes/material/fonts/os_600.woff2 b/themes/material/fonts/os_600.woff2
new file mode 100644
index 000000000..7e5e42c26
Binary files /dev/null and b/themes/material/fonts/os_600.woff2 differ
diff --git a/themes/material/fonts/os_700.woff b/themes/material/fonts/os_700.woff
new file mode 100644
index 000000000..a0a331e74
Binary files /dev/null and b/themes/material/fonts/os_700.woff differ
diff --git a/themes/material/fonts/os_700.woff2 b/themes/material/fonts/os_700.woff2
new file mode 100644
index 000000000..9ab88e241
Binary files /dev/null and b/themes/material/fonts/os_700.woff2 differ
diff --git a/themes/material/fonts/os_800.woff b/themes/material/fonts/os_800.woff
new file mode 100644
index 000000000..40e169012
Binary files /dev/null and b/themes/material/fonts/os_800.woff differ
diff --git a/themes/material/fonts/os_800.woff2 b/themes/material/fonts/os_800.woff2
new file mode 100644
index 000000000..a4ec23e5e
Binary files /dev/null and b/themes/material/fonts/os_800.woff2 differ