more work on emojis
@@ -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']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
60
Zotlabs/Module/Emoji.php
Normal file
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 )",
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 842 B |
|
Before Width: | Height: | Size: 901 B |
|
Before Width: | Height: | Size: 935 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 812 B |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 757 B |
|
Before Width: | Height: | Size: 575 B |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 435 B |
@@ -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
|
||||
|
||||
|
||||
BIN
images/emoji/astonished_face.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
images/emoji/bottle_with_popping_cork.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
images/emoji/clapping_hands.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
images/emoji/disappointed_face.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
images/emoji/grinning_face.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
images/emoji/kiss_mark.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
images/emoji/red_heart.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
images/emoji/sleeping_face.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
images/emoji/slightly_smiling_face.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
images/emoji/smiling_face_with_halo.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
images/emoji/smiling_face_with_horns.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
images/emoji/winking_face_with_tongue.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
@@ -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'] ?? ''),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||