diff options
36 files changed, 217 insertions, 38 deletions
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 43f7386e7..e19499c56 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -642,7 +642,7 @@ class Activity { break; case 'Emoji': - $ret[] = ['ttype' => TERM_EMOJI, 'url' => $t['icon']['url'], 'term' => escape_tags($t['name'])]; + $ret[] = ['ttype' => TERM_EMOJI, 'url' => $t['id'], 'term' => escape_tags($t['name']), 'imgurl' => $t['icon']['url']]; break; default: @@ -677,6 +677,10 @@ class Activity { $ret[] = ['type' => 'Bookmark', 'href' => $t['url'], 'name' => $t['term']]; break; + case TERM_EMOJI: + $ret[] = ['type' => 'Emoji', 'id' => $t['url'], 'name' => $t['term'], 'icon' => ['type' => 'Image', 'url' => $t['imgurl']]]; + break; + default: break; } @@ -976,10 +980,12 @@ class Activity { return []; } +/* this should not be needed $t = self::encode_taxonomy($i); if ($t) { $ret['tag'] = $t; } +*/ $a = self::encode_attachment($i, true); if ($a) { @@ -997,6 +1003,7 @@ class Activity { ]; call_hooks('encode_activity', $hookinfo); + return $hookinfo['encoded']; } @@ -2179,9 +2186,17 @@ class Activity { // Pleroma reactions $t = trim(self::get_textfield($act->data, 'content')); + $content['content'] = $t; + // Unicode emojis if (grapheme_strlen($t) === 1) { - $content['content'] = $t; + $content['content'] = '<h1>' . $t . '</h1>'; + } + + $a = self::decode_taxonomy($act->data); + + if ($a) { + $s['term'] = $a; } } } @@ -2885,7 +2900,13 @@ class Activity { if (isset($item['term']) && !PConfig::Get($channel['channel_id'], 'system', 'no_smilies')) { foreach ($item['term'] as $t) { if ($t['ttype'] === TERM_EMOJI) { - $item['body'] = str_replace($t['term'], '[img class="smiley emoji custom-emoji" alt="' . $t['term'] . '" title="' . $t['term'] . '"]' . $t['url'] . '[/img]', $item['body']); + $class = 'emoji'; + $shortname = ':' . trim($t['term'], ':') . ':'; + if (is_solo_string($shortname, $item['body'])) { + $class .= ' single-emoji'; + } + + $item['body'] = str_replace($shortname, '[img class="' . $class . '" alt="' . $t['term'] . '" title="' . $t['term'] . '"]' . ($t['imgurl'] ?: $t['url']) . '[/img]', $item['body']); } } } diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 42d76bf17..8f364e945 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -19,7 +19,7 @@ class ThreadItem { private $comment_box_template = 'comment_item.tpl'; private $commentable = false; // list of supported reaction emojis - a site can over-ride this via config system.reactions - private $reactions = ['1f60a','1f44f','1f37e','1f48b','1f61e','2665','1f606','1f62e','1f634','1f61c','1f607','1f608']; + private $reactions = ['slightly_smiling_face','clapping_hands','bottle_with_popping_cork','kiss_mark','disappointed_face','red_heart','grinning_face','astonished_face','sleeping_face','winking_face_with_tongue','smiling_face_with_halo','smiling_face_with_horns']; private $toplevel = false; private $children = array(); private $parent = null; diff --git a/Zotlabs/Module/Emoji.php b/Zotlabs/Module/Emoji.php new file mode 100644 index 000000000..595c9fc60 --- /dev/null +++ b/Zotlabs/Module/Emoji.php @@ -0,0 +1,60 @@ +<?php +namespace Zotlabs\Module; + +use Zotlabs\Web\Controller; +use Zotlabs\Daemon\Master; +use Zotlabs\Lib\ActivityStreams; +use App; + + +class Emoji extends Controller { + + function init() { + + $shortname = argv(1); + + if (!$shortname) { + killme(); + } + + $emojis = get_emojis(); + + if (!isset($emojis[$shortname])) { + killme(); + } + + $emoji = $emojis[$shortname]; + +hz_syslog(print_r($emoji, true)); + + + if (!file_exists($emoji['filepath'])) { + killme(); + } + + $image = getimagesize($emoji['filepath']); + + if(ActivityStreams::is_as_request()) { + $last_modified = date(ATOM_TIME, filemtime($emoji['filepath'])); + + $obj = [ + 'id' => z_root() . '/emoji/' . $shortname, + 'type' => 'Emoji', + 'name' => $emoji['shortname'], + 'updated' => $last_modified, + 'icon' => [ + 'type' => 'Image', + 'mediaType' => $image['mime'], + 'url' => z_root() . '/' . $emoji['filepath'] + ] + ]; + + as_return_and_die($obj); + } + + header('Content-Type: ' . $image['mime']); + echo file_get_contents($emoji['filepath']); + killme(); + } + +} diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 5c802f557..b158ed4e0 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -938,6 +938,30 @@ class Item extends Controller { } } + if (preg_match_all('/(\:(\w|\+|\-)+\:)(?=|[\!\.\?]|$)/', $body, $match)) { + // emoji shortcodes + $emojis = get_emojis(); + foreach ($match[0] as $mtch) { + $shortname = trim($mtch, ':'); + + if (!isset($emojis[$shortname])) { + continue; + } + + $emoji = $emojis[$shortname]; + + $post_tags[] = [ + 'uid' => $profile_uid, + 'ttype' => TERM_EMOJI, + 'otype' => TERM_OBJ_POST, + 'term' => trim($mtch), + 'url' => z_root() . '/emoji/' . $shortname, + 'imgurl' => z_root() . '/' . $emoji['filepath'] + ]; + } + } + + // BBCODE end alert } @@ -958,6 +982,10 @@ class Item extends Controller { } } + + + + if ($orig_post) { // preserve original tags $t = q("select * from term where oid = %d and otype = %d and uid = %d and ttype in ( %d, %d, %d )", diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index 6a3b525b2..e04b9b257 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -24,7 +24,15 @@ class React extends Controller { return; } - $emoji = $_REQUEST['emoji']; + $shortname = $_REQUEST['emoji']; + + $emojis = get_emojis(); + + if (!isset($emojis[$shortname])) { + return; + } + + $emoji = $emojis[$shortname]; if (!$emoji) { return; @@ -62,10 +70,19 @@ class React extends Controller { $n['uuid'] = $uuid; $n['mid'] = z_root() . '/item/' . $uuid; $n['verb'] = 'Create'; - $n['body'] = '[zmg=32x32]' . z_root() . '/images/emoji/' . $emoji . '.png[/zmg]'; + $n['body'] = $emoji['shortname']; //'[img class="emoji single-emoji"]' . z_root() . '/' . $emoji['filepath'] . '[/img]'; $n['author_xchan'] = $channel['channel_hash']; - $n['obj'] = Activity::fetch_item(['id' => $item['mid']]); - $n['obj_type'] = ((array_path_exists('obj/type', $n)) ? $n['obj']['type'] : EMPTY_STR); + // $n['obj'] = Activity::fetch_item(['id' => $i[0]['mid']]); + // $n['obj_type'] = ((array_path_exists('obj/type', $n)) ? $n['obj']['type'] : EMPTY_STR); + + $n['term'][] = [ + 'uid' => $channel['channel_id'], + 'ttype' => TERM_EMOJI, + 'otype' => TERM_OBJ_POST, + 'term' => $emoji['shortname'], + 'url' => z_root() . '/emoji/' . $shortname, + 'imgurl' => z_root() . '/' . $emoji['filepath'] + ]; $x = item_store($n); diff --git a/Zotlabs/Module/Smilies.php b/Zotlabs/Module/Smilies.php index efac07f84..7dde8c834 100644 --- a/Zotlabs/Module/Smilies.php +++ b/Zotlabs/Module/Smilies.php @@ -4,18 +4,8 @@ namespace Zotlabs\Module; class Smilies extends \Zotlabs\Web\Controller { - function get() { - if (\App::$argv[1]==="json"){ - $tmp = list_smilies(); - $results = array(); - for($i = 0; $i < count($tmp['texts']); $i++) { - $results[] = array('text' => $tmp['texts'][$i], 'icon' => $tmp['icons'][$i]); - } - json_return_and_die($results); - } - else { - return smilies('',true); - } + function init() { + json_return_and_die(get_emojis()); } - + } diff --git a/images/emoji/1f37e.png b/images/emoji/1f37e.png Binary files differdeleted file mode 100644 index 285a79a93..000000000 --- a/images/emoji/1f37e.png +++ /dev/null diff --git a/images/emoji/1f44f.png b/images/emoji/1f44f.png Binary files differdeleted file mode 100644 index b0ffe9289..000000000 --- a/images/emoji/1f44f.png +++ /dev/null diff --git a/images/emoji/1f48b.png b/images/emoji/1f48b.png Binary files differdeleted file mode 100644 index 85e6dcfc4..000000000 --- a/images/emoji/1f48b.png +++ /dev/null diff --git a/images/emoji/1f606.png b/images/emoji/1f606.png Binary files differdeleted file mode 100644 index d94e9505b..000000000 --- a/images/emoji/1f606.png +++ /dev/null diff --git a/images/emoji/1f607.png b/images/emoji/1f607.png Binary files differdeleted file mode 100644 index 57f515112..000000000 --- a/images/emoji/1f607.png +++ /dev/null diff --git a/images/emoji/1f608.png b/images/emoji/1f608.png Binary files differdeleted file mode 100644 index cc2c5f1ec..000000000 --- a/images/emoji/1f608.png +++ /dev/null diff --git a/images/emoji/1f60a.png b/images/emoji/1f60a.png Binary files differdeleted file mode 100644 index aac1a424a..000000000 --- a/images/emoji/1f60a.png +++ /dev/null diff --git a/images/emoji/1f61c.png b/images/emoji/1f61c.png Binary files differdeleted file mode 100644 index 4817eaa3d..000000000 --- a/images/emoji/1f61c.png +++ /dev/null diff --git a/images/emoji/1f61e.png b/images/emoji/1f61e.png Binary files differdeleted file mode 100644 index efe4e67e2..000000000 --- a/images/emoji/1f61e.png +++ /dev/null diff --git a/images/emoji/1f62e.png b/images/emoji/1f62e.png Binary files differdeleted file mode 100644 index a62cd27e1..000000000 --- a/images/emoji/1f62e.png +++ /dev/null diff --git a/images/emoji/1f634.png b/images/emoji/1f634.png Binary files differdeleted file mode 100644 index 9ecf600d6..000000000 --- a/images/emoji/1f634.png +++ /dev/null diff --git a/images/emoji/2665.png b/images/emoji/2665.png Binary files differdeleted file mode 100644 index 638cb72dc..000000000 --- a/images/emoji/2665.png +++ /dev/null diff --git a/images/emoji/README b/images/emoji/README index ab478b753..6ac43096d 100644 --- a/images/emoji/README +++ b/images/emoji/README @@ -1,2 +1,7 @@ -These files supplied by emojione. License is CC BY 4.0. Attribution is required for commercial use. -See http://emojione.com +Images are provided by Emojitwo formerly Emojione +https://emojitwo.github.io +https://www.emojione.com + +Creative Commons Attribution International 4.0 (CC-BY 4.0) +https://creativecommons.org/licenses/by/4.0/legalcode + diff --git a/images/emoji/astonished_face.png b/images/emoji/astonished_face.png Binary files differnew file mode 100644 index 000000000..6f326e925 --- /dev/null +++ b/images/emoji/astonished_face.png diff --git a/images/emoji/bottle_with_popping_cork.png b/images/emoji/bottle_with_popping_cork.png Binary files differnew file mode 100644 index 000000000..90ddd0e03 --- /dev/null +++ b/images/emoji/bottle_with_popping_cork.png diff --git a/images/emoji/clapping_hands.png b/images/emoji/clapping_hands.png Binary files differnew file mode 100644 index 000000000..4da00ec4d --- /dev/null +++ b/images/emoji/clapping_hands.png diff --git a/images/emoji/disappointed_face.png b/images/emoji/disappointed_face.png Binary files differnew file mode 100644 index 000000000..c7c2f397b --- /dev/null +++ b/images/emoji/disappointed_face.png diff --git a/images/emoji/grinning_face.png b/images/emoji/grinning_face.png Binary files differnew file mode 100644 index 000000000..643459c53 --- /dev/null +++ b/images/emoji/grinning_face.png diff --git a/images/emoji/kiss_mark.png b/images/emoji/kiss_mark.png Binary files differnew file mode 100644 index 000000000..d563361d6 --- /dev/null +++ b/images/emoji/kiss_mark.png diff --git a/images/emoji/red_heart.png b/images/emoji/red_heart.png Binary files differnew file mode 100644 index 000000000..f05141f78 --- /dev/null +++ b/images/emoji/red_heart.png diff --git a/images/emoji/sleeping_face.png b/images/emoji/sleeping_face.png Binary files differnew file mode 100644 index 000000000..9e524b9b4 --- /dev/null +++ b/images/emoji/sleeping_face.png diff --git a/images/emoji/slightly_smiling_face.png b/images/emoji/slightly_smiling_face.png Binary files differnew file mode 100644 index 000000000..281e068e4 --- /dev/null +++ b/images/emoji/slightly_smiling_face.png diff --git a/images/emoji/smiling_face_with_halo.png b/images/emoji/smiling_face_with_halo.png Binary files differnew file mode 100644 index 000000000..1bfee01ae --- /dev/null +++ b/images/emoji/smiling_face_with_halo.png diff --git a/images/emoji/smiling_face_with_horns.png b/images/emoji/smiling_face_with_horns.png Binary files differnew file mode 100644 index 000000000..50f938ea8 --- /dev/null +++ b/images/emoji/smiling_face_with_horns.png diff --git a/images/emoji/winking_face_with_tongue.png b/images/emoji/winking_face_with_tongue.png Binary files differnew file mode 100644 index 000000000..e786f0e47 --- /dev/null +++ b/images/emoji/winking_face_with_tongue.png diff --git a/include/items.php b/include/items.php index e26366af5..a5a23650e 100644 --- a/include/items.php +++ b/include/items.php @@ -1999,14 +1999,15 @@ function item_store($arr, $allow_exec = false, $deliver = true) { if(($terms) && (is_array($terms))) { foreach($terms as $t) { - q("insert into term (uid,oid,otype,ttype,term,url) - values(%d,%d,%d,%d,'%s','%s') ", + q("insert into term (uid,oid,otype,ttype,term,url,imgurl) + values(%d,%d,%d,%d,'%s','%s','%s') ", intval($arr['uid']), intval($current_post), intval(TERM_OBJ_POST), intval($t['ttype']), dbesc($t['term']), - dbesc($t['url']) + dbesc($t['url']), + dbesc($t['imgurl'] ?? ''), ); } diff --git a/include/network.php b/include/network.php index d41ba198d..a5c14f9d1 100644 --- a/include/network.php +++ b/include/network.php @@ -423,7 +423,7 @@ function json_return_and_die($x, $content_type = 'application/json') { killme(); } -function as_return_and_die($obj, $channel) { +function as_return_and_die($obj, $channel = []) { $ret = Activity::build_packet($obj, $channel); logger('data: ' . jindent($ret), LOGGER_DATA); @@ -433,8 +433,10 @@ function as_return_and_die($obj, $channel) { $headers['Digest'] = HTTPSig::generate_digest_header($ret); $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; - $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel)); - HTTPSig::set_headers($h); + if ($channel) { + $h = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel)); + HTTPSig::set_headers($h); + } echo $ret; killme(); diff --git a/include/text.php b/include/text.php index 26bf94828..baf1f770b 100644 --- a/include/text.php +++ b/include/text.php @@ -1270,6 +1270,33 @@ function sslify($s) { return $s; } +function get_emojis() { + $emojis = [ + // Reactions (emojitwo emojis) + 'astonished_face' => ['shortname' => ':astonished_face:', 'filepath' => 'images/emoji/astonished_face.png'], + 'bottle_with_popping_cork' => ['shortname' => ':bottle_with_popping_cork:', 'filepath' => 'images/emoji/bottle_with_popping_cork.png'], + 'clapping_hands' => ['shortname' => ':clapping_hands:', 'filepath' => 'images/emoji/clapping_hands.png'], + 'disappointed_face' => ['shortname' => ':disappointed_face:', 'filepath' => 'images/emoji/disappointed_face.png'], + 'grinning_face' => ['shortname' => ':grinning_face:', 'filepath' => 'images/emoji/grinning_face.png'], + 'kiss_mark' => ['shortname' => ':kiss_mark:', 'filepath' => 'images/emoji/kiss_mark.png'], + 'red_heart' => ['shortname' => ':red_heart:', 'filepath' => 'images/emoji/red_heart.png'], + 'sleeping_face' => ['shortname' => ':sleeping_face:', 'filepath' => 'images/emoji/sleeping_face.png'], + 'slightly_smiling_face' => ['shortname' => ':slightly_smiling_face:', 'filepath' => 'images/emoji/slightly_smiling_face.png'], + 'smiling_face_with_halo' => ['shortname' => ':smiling_face_with_halo:', 'filepath' => 'images/emoji/smiling_face_with_halo.png'], + 'smiling_face_with_horns' => ['shortname' => ':smiling_face_with_horns:', 'filepath' => 'images/emoji/smiling_face_with_horns.png'], + 'winking_face_with_tongue' => ['shortname' => ':winking_face_with_tongue:', 'filepath' => 'images/emoji/winking_face_with_tongue.png'], + + 'facepalm' => ['shortname' => ':facepalm:', 'filepath' => 'images/emoticons/smiley-facepalm.gif'] + ]; + + call_hooks('get_emojis', $emojis); + + return $emojis; +} + +function is_solo_string(string $emoji, string $body) : bool { + return empty(trim(str_replace($emoji, '', $body, $count))) && $count === 1; +} /** * @brief Function to list all smilies, both internal and from addons. @@ -1386,10 +1413,34 @@ function smilies($s, $sample = false) { || (local_channel() && intval(get_pconfig(local_channel(), 'system', 'no_smilies')))) return $s; + $s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism', 'smile_shield', $s); $s = preg_replace_callback('/<[a-z]+ .*?>/ism', 'smile_shield', $s); + if (preg_match_all('/(\:(\w|\+|\-)+\:)(?=|[\!\.\?]|$)/', $s, $match)) { + // emoji shortcodes + $emojis = get_emojis(); + foreach ($match[0] as $mtch) { + $name = trim($mtch, ':'); + + if (!isset($emojis[$name])) { + continue; + } + + $emoji = $emojis[$name]; + + $class = 'emoji'; + if (is_solo_string($mtch, $s)) { + $class .= ' single-emoji'; + } + + $img = '<img class="' . $class . '" src="' . $emoji['filepath'] . '" alt="' . $emoji['shortname'] . '" title="' . $emoji['shortname'] . '" />'; + + string_replace($emoji['shortname'], $img, $s); + } + } +/* $params = list_smilies(); $params['string'] = $s; @@ -1400,9 +1451,9 @@ function smilies($s, $sample = false) { } } else { $params['string'] = preg_replace_callback('/<(3+)/','preg_heart',$params['string']); - $s = str_replace($params['texts'],$params['icons'],$params['string']); + $s = str_replace($params['texts'], $params['icons'], $params['string']); } - +*/ $s = preg_replace_callback('/<!--base64:(.*?)-->/ism', 'smile_unshield', $s); diff --git a/view/css/conversation.css b/view/css/conversation.css index 3af51d102..54b12ac16 100644 --- a/view/css/conversation.css +++ b/view/css/conversation.css @@ -299,13 +299,17 @@ code.inline-code { text-decoration: overline; } -img.smiley.emoji { - height: .9em; +img.emoji { + height: 1rem; vertical-align: baseline; - margin-bottom: -.1em; + margin-bottom: -.1rem; } -img.smiley.emoji:hover { +img.emoji.single-emoji { + height: 2rem; +} + +img.emoji:not(.single-emoji):hover { transform: scale(2); transition: transform .1s ease-out; filter: drop-shadow(0px 0px 1px rgba(0, 0, 0, .5)); diff --git a/view/js/autocomplete.js b/view/js/autocomplete.js index 8edd8dafa..7d6ddb1c4 100644 --- a/view/js/autocomplete.js +++ b/view/js/autocomplete.js @@ -45,7 +45,7 @@ function contact_format(item) { } function smiley_format(item) { - return "<div class='dropdown-item'>" + item.icon + ' ' + item.text + "</div>"; + return "<div class='dropdown-item'><img class='emoji' src='" + item.filepath + "'> " + item.shortname.replaceAll(':', '') + "</div>"; } function bbco_format(item) { @@ -193,8 +193,8 @@ function string2bb(element) { match: /(^|\s)(:[a-z0-9_:]{2,})$/, index: 2, cache: true, - search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.text.indexOf(term.substr(1)) !== -1 ? entry : null; })); }); }, - replace: function(item) { return "$1" + item.text + ' '; }, + search: function(term, callback) { $.getJSON('/smilies/json').done(function(data) { callback($.map(data, function(entry) { return entry.shortname.indexOf(term.substr(1)) !== -1 ? entry : null; })); }); }, + replace: function(item) { return "$1" + item.shortname + ' '; }, context: function(text) { return text.toLowerCase(); }, template: smiley_format }; |