Browse Source

Chat bubbles a bit more compact

Display single emojis as small stickers
pull/784/head
Timothée Jaussoin 7 years ago
parent
commit
4537778c60
  1. 2
      CHANGELOG.md
  2. 6
      app/Message.php
  3. 13
      app/widgets/Chat/Chat.php
  4. 3
      app/widgets/Notifications/Notifications.php
  5. 3
      app/widgets/Post/Post.php
  6. 45
      src/Movim/Emoji.php
  7. 14
      themes/material/css/listn.css

2
CHANGELOG.md

@ -20,6 +20,8 @@ v0.14.1 (trunk)
* CSS fixes in Forms
* Disable the dropdown in Form if there is only one choice
* Add support for embeded images in Forms (for CAPTCHA)
* Chat bubbles a bit more compact
* Display single emojis as small stickers
v0.14
---------------------------

6
app/Message.php

@ -283,12 +283,6 @@ class Message extends Model
}
}
public function convertEmojis()
{
$emoji = \Movim\Emoji::getInstance();
$this->body = addHFR($emoji->replace($this->body));
}
public function isTrusted()
{
/*$rd = new \Modl\RosterLinkDAO;

13
app/widgets/Chat/Chat.php

@ -664,11 +664,14 @@ class Chat extends \Movim\Widget\Base
$message->jidto = echapJS($message->jidto);
$message->jidfrom = echapJS($message->jidfrom);
$emoji = \Movim\Emoji::getInstance();
if (isset($message->html)) {
$message->body = $message->html;
} else {
$message->addUrls();
$message->convertEmojis();
$message->body = $emoji->replace($message->body);
$message->body = addHFR($message->body);
}
if (isset($message->subject) && $message->type == 'headline') {
@ -697,6 +700,14 @@ class Chat extends \Movim\Widget\Base
}
}
// Jumbo emoji
if ($emoji->isSingleEmoji()) {
$message->sticker = [
'url' => $emoji->getLastSingleEmojiURL(),
'height' => 60
];
}
// Attached file
if (isset($message->file)) {
// We proxify pictures links even if they are advertized as small ones

3
app/widgets/Notifications/Notifications.php

@ -148,7 +148,6 @@ class Notifications extends Base
}
}
$emoji = \Movim\Emoji::getInstance();
$notifs = \App\Post::whereIn('parent_id', function ($query) {
$query->select('id')
->from('posts')
@ -161,7 +160,7 @@ class Notifications extends Base
if (!$since) $since = date(SQL_DATE, 0);
$view = $this->tpl();
$view->assign('hearth', $emoji->replace('♥'));
$view->assign('hearth', addEmojis('♥'));
$view->assign('notifs', $notifs);
$view->assign('since', $since);
$view->assign('invitations', $invitations);

3
app/widgets/Post/Post.php

@ -172,11 +172,10 @@ class Post extends Base
public function prepareComments(\App\Post $post, $public = false)
{
$emoji = \Movim\Emoji::getInstance();
$view = $this->tpl();
$view->assign('post', $post);
$view->assign('public', $public);
$view->assign('hearth', $emoji->replace('♥'));
$view->assign('hearth', addEmojis('♥'));
return $view->draw('_post_comments');
}

45
src/Movim/Emoji.php

@ -25,15 +25,18 @@ class Emoji
{
protected static $instance = null;
private $_emoji;
private $_string;
private $_emojisCount = 0;
private $_lastEmojiURL = null;
private $_regex = [
/* some easy cases first */
// Some easy cases first
'/[#*0-9]\x{20E3}
|\x{1F3F3}(?:\x{FE0F}\x{200D}\x{1F308})?
|\x{1F3F4}(?:\x{200D}\x{2620}\x{FE0F}|\x{E0067}\x{E0062}
(?:\x{E0065}\x{E006E}\x{E0067}|\x{E0073}\x{E0063}\x{E0074}|\x{E0077}\x{E006C}\x{E0073})\x{E007F})?
|\x{1F441}(?:\x{200D}\x{1F5E8})?
/ux',
/* everything starting with 1F468 or 1F469 */
// Everything starting with 1F468 or 1F469
'/[\x{1F468}\x{1F469}]
(?:\x{200D}\x{2764}\x{FE0F}\x{200D}(?:\x{1F48B}\x{200D})?[\x{1F468}\x{1F469}]
|(?:\x{200D}[\x{1F468}\x{1F469}])?
@ -44,14 +47,14 @@ class Emoji
|[\x{1F33E}\x{1F373}\x{1F393}\x{1F3A4}\x{1F3A8}\x{1F3EB}\x{1F3ED}\x{1F4BB}\x{1F4BC}\x{1F527}\x{1F52C}\x{1F680}\x{1F692}]
)
)/ux',
/* some more combinations (order is important!) */
// Some more combinations (order is important!)
'/[\x{26F9}\x{1F3C3}-\x{1F3CC}\x{1F46E}\x{1F46F}\x{1F461}-\x{1F477}\x{1F481}-\x{1F487}\x{1F575}\x{1F645}-\x{1F64E}\x{1F6A3}\x{1F6B4}-\x{1F6B6}\x{1F926}\x{1F937}-\x{1F93E}\x{1F9D6}-\x{1F9DF}]
[\x{FE0F}\x{1F3FB}-\x{1F3FF}]?
\x{200D}[\x{2640}\x{2642}]\x{FE0F}
/ux',
'/[\x{261D}\x{26F7}-\x{270D}\x{1F1E6}-\x{1F1FF}\x{1F385}\x{1F3C2}-\x{1F3CC}\x{1F442}-\x{1F487}\x{1F4AA}\x{1F574}-\x{1F596}\x{1F645}-\x{1F6CC}\x{1F918}-\x{1F9DD}]
[\x{1F1E6}-\x{1F1FF}\x{1F3FB}-\x{1F3FF}]/ux',
/* individual codepoints last */
// Individual codepoints last
'/[\x{203C}\x{2049}\x{2139}-\x{21AA}\x{231A}-\x{23FA}\x{24C2}\x{25AA}-\x{27BF}\x{2934}-\x{2B55}\x{3030}-\x{3299}\x{1F004}-\x{1F9E6}]/u'
];
@ -60,8 +63,10 @@ class Emoji
$this->_emoji = require('Emoji/CompiledEmoji.php');
}
public function replace($string)
public function replace($string): string
{
$this->_string = $string;
return preg_replace_callback($this->_regex, function ($matches) {
$astext = implode('-',
array_map('dechex',
@ -69,31 +74,49 @@ class Emoji
)
);
/* Do we know this character? */
if (!isset($this->_emoji[$astext])) {
/* No, return match unchanged */
return $matches[0];
}
/* Yes, replace */
$this->_emojisCount++;
$this->_lastEmojiURL = BASE_URI . 'themes/' .
\App\Configuration::get()->theme .
'/img/emojis/svg/' . $astext . '.svg';
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($img = $dom->createElement('img'));
$img->setAttribute('class', 'emoji');
$img->setAttribute('alt', $this->_emoji[$astext]);
$img->setAttribute('title', $this->_emoji[$astext]);
$img->setAttribute('src', BASE_URI . 'themes/' .
\App\Configuration::get()->theme .
'/img/emojis/svg/' . $astext . '.svg');
$img->setAttribute('src', $this->_lastEmojiURL);
return $dom->saveXML($dom->documentElement);
}, $string);
}
public function isSingleEmoji(): bool
{
// grapheme_strlen is more accurate and takes into account joined emojis
$stringLength = extension_loaded('intl')
? grapheme_strlen($this->_string)
: mb_strlen($this->_string);
return $this->_emojisCount === 1 && $stringLength === 1;
}
public function getLastSingleEmojiURL()
{
return $this->_lastEmojiURL;
}
public static function getInstance()
{
if (!isset(static::$instance)) {
static::$instance = new Emoji;
}
static::$instance->_emojisCount = 0;
static::$instance->_string = null;
static::$instance->_lastEmojiUrl = null;
return static::$instance;
}

14
themes/material/css/listn.css

@ -399,24 +399,10 @@ ul li div.bubble span.info {
ul li div.bubble:after {
content: attr(data-publishedprepared);
clear: both;
line-height: 3rem;
text-align: left;
}
ul li div.bubble.sticker:after {
padding-top: 0.5rem;
}
ul li.oppose div.bubble:after {
right: 9rem;
text-align: right;
}
ul li:not(.oppose) div.bubble:after {
left: 0;
}
ul li .quote {
font-style: italic;
}

Loading…
Cancel
Save