Browse Source

- Merge with edhelas

pull/16/head
Jaussoin Timothée 11 years ago
parent
commit
d837445edb
  1. 12
      app/helpers/DateHelper.php
  2. 58
      app/helpers/StringHelper.php
  3. 2
      app/models/message/Message.php
  4. 3
      app/views/page.tpl
  5. 100
      app/widgets/Chat/Chat.php
  6. 10
      app/widgets/Chat/_chat.tpl
  7. 17
      app/widgets/Chat/_chat_bubble.tpl
  8. 5
      app/widgets/Chat/_chat_bubble_room.tpl
  9. 2
      app/widgets/Chat/_chat_header.tpl
  10. 44
      app/widgets/Chat/_chat_message.tpl
  11. 21
      app/widgets/Chat/_chat_messages.tpl
  12. 31
      app/widgets/Chat/chat.css
  13. 62
      app/widgets/Chat/chat.js
  14. 83
      app/widgets/Chat/chat_otr.js
  15. 2
      app/widgets/Chats/chats.js
  16. 2
      app/widgets/Rooms/Rooms.php
  17. 6
      linker.php
  18. 18
      themes/material/css/color.css
  19. 30
      themes/material/css/fonts.css
  20. 3
      themes/material/css/style.css
  21. BIN
      themes/material/fonts/os_300.woff
  22. BIN
      themes/material/fonts/os_300.woff2
  23. BIN
      themes/material/fonts/os_400.woff
  24. BIN
      themes/material/fonts/os_400.woff2
  25. BIN
      themes/material/fonts/os_600.woff
  26. BIN
      themes/material/fonts/os_600.woff2
  27. BIN
      themes/material/fonts/os_700.woff
  28. BIN
      themes/material/fonts/os_700.woff2
  29. BIN
      themes/material/fonts/os_800.woff
  30. BIN
      themes/material/fonts/os_800.woff2

12
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;
}

58
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);
}

2
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 = '
{

3
app/views/page.tpl

@ -19,8 +19,8 @@
<script src="<?php echo BASE_URI; ?>app/assets/js/otr/dep/crypto.js"></script>
<script src="<?php echo BASE_URI; ?>app/assets/js/otr/dep/eventemitter.js"></script>
<script src="<?php echo BASE_URI; ?>app/assets/js/otr/otr.js"></script>
<script src="<?php echo BASE_URI; ?>app/assets/js/cycle.js"></script>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700,800' rel='stylesheet' type='text/css'>
<meta name="viewport" content="width=device-width, user-scalable=no">
<?php
@ -32,6 +32,7 @@
$this->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');

100
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()

10
app/widgets/Chat/_chat.tpl

@ -1,6 +1,6 @@
<div id="{$jid}_discussion" class="contained">
<section id="{$jid}_messages">
{$messages}
<ul class="{if="$muc"}thin simple{else}middle{/if}" id="{$jid}_conversation"></ul>
</section>
<div id="{$jid}_state"></div>
</div>
@ -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')}"
></textarea>

17
app/widgets/Chat/_chat_bubble.tpl

@ -0,0 +1,17 @@
<li {if="$me"}class="oppose"{/if}>
{$url = $contact->getPhoto('s')}
{if="$url"}
<span class="icon bubble">
<img src="{$url}">
</span>
{else}
<span class="icon bubble color {$contact->jid|stringToColor}">
<i class="md md-person"></i>
</span>
{/if}
<div class="bubble">
<div></div>
<span class="info"></span>
</div>
</li>

5
app/widgets/Chat/_chat_bubble_room.tpl

@ -0,0 +1,5 @@
<li class="room">
<span class="info"></span>
<span class="user"></span>
<div></div>
</li>

2
app/widgets/Chat/_chat_header.tpl

@ -10,7 +10,7 @@
</span>
</li>
</ul>
<h2 class="active r1" onclick="MovimTpl.hidePanel(); Chat_ajaxGet();">
<h2 id="chat_header" class="active r1" onclick="MovimTpl.hidePanel(); Chat_ajaxGet();">
<span id="back" class="icon"><i class="md md-arrow-back"></i></span>
{if="$contact != null"}
{$contact->getTrueName()}

44
app/widgets/Chat/_chat_message.tpl

@ -1,44 +0,0 @@
{if="$message->body != ''"}
<li {if="$message->jidfrom != $jid"}class="oppose"{/if}>
{if="$message->jidfrom == $jid"}
{$url = $contact->getPhoto('s')}
{if="$url"}
<span class="icon bubble">
<img src="{$url}">
</span>
{elseif="$message->type == 'groupchat'"}
<span class="icon bubble color {$message->resource|stringToColor}">
<i class="md md-person"></i>
</span>
{else}
<span class="icon bubble color {$contact->jid|stringToColor}">
<i class="md md-person"></i>
</span>
{/if}
{else}
<span class="icon bubble">
<img src="{$me->getPhoto('s')}">
</span>
{/if}
{if="preg_match('#^\/me#', $message->body)"}
{$message->body = '* '.substr($message->body, 3)}
{$class = 'quote'}
{else}
{$class = ''}
{/if}
<div class="bubble {$class}">
{if="preg_match('#^\?OTR#', $message->body)"}
<i class="md md-lock"></i><div class="encrypted">{$c->__('message.encrypted')}</div>
<!--<div class="encrypted">{$message->body}</div>-->
{else}
<div>{if="isset($message->html)"}{$message->html|prepareString}{else}{$message->body|htmlentities:ENT_COMPAT,'UTF-8'|prepareString}{/if}</div>
{/if}
<span class="info">{$message->published|strtotime|prepareDate}</span>
{if="$message->type == 'groupchat'"}
<span class="info">{$message->resource} - </span>
{/if}
</div>
</li>
{/if}

21
app/widgets/Chat/_chat_messages.tpl

@ -1,21 +0,0 @@
<ul class="middle" id="{$jid}_conversation">
{$messages_html}
{if="$status != false"}
<li {if="$myself != false"}class="oppose"{/if}>
<span class="icon bubble">
{if="$myself == false"}
<img src="{$contact->getPhoto('s')}">
{else}
<img src="{$me->getPhoto('s')}">
{/if}
</span>
<div class="bubble">
{if="$status == 'composing'"}
<i class="md md-mode-edit"></i> {$c->__('message.composing')}
{else}
<i class="md md-mode-edit"></i> {$c->__('message.paused')}
{/if}
</div>
</li>
{/if}
</ul>

31
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;

62
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 = '<b>' + message.resource + '</b>: ' + message.body;
bubble.querySelector('div.bubble').className = 'bubble room';
} else {
}*/
movim_append(id, bubble.outerHTML);
MovimTpl.scrollPanel();
}
}

83
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++;
}
}
}

2
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) {

2
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)
{

6
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 == '</stream:stream>') {
$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));
}

18
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 {

30
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');
}

3
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 */

BIN
themes/material/fonts/os_300.woff

BIN
themes/material/fonts/os_300.woff2

BIN
themes/material/fonts/os_400.woff

BIN
themes/material/fonts/os_400.woff2

BIN
themes/material/fonts/os_600.woff

BIN
themes/material/fonts/os_600.woff2

BIN
themes/material/fonts/os_700.woff

BIN
themes/material/fonts/os_700.woff2

BIN
themes/material/fonts/os_800.woff

BIN
themes/material/fonts/os_800.woff2

Loading…
Cancel
Save