From ac26611e05928c7edff3c2a4a66e06977d7165f1 Mon Sep 17 00:00:00 2001 From: Silke Meyer Date: Wed, 3 Feb 2016 20:39:50 +0100 Subject: [PATCH 001/391] Updated docs about Let's Encrypt --- doc/SSL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/SSL.md b/doc/SSL.md index a72eec2a16..bcff929fe5 100644 --- a/doc/SSL.md +++ b/doc/SSL.md @@ -90,8 +90,8 @@ If you run your own server, upload the files and check out the Mozilla wiki link Let's encrypt --- -If you run your own server and you control your name server, the "Let's encrypt" initiative might become an interesting alternative. -Their offer is not ready, yet. +If you run your own server, the "Let's encrypt" initiative might become an interesting alternative. +Their offer is in public beta right now. Check out [their website](https://letsencrypt.org/) for status updates. Web server settings From 5559c02662e48daea1fdb78ae5797959ee379b4d Mon Sep 17 00:00:00 2001 From: Silke Meyer Date: Wed, 3 Feb 2016 21:49:07 +0100 Subject: [PATCH 002/391] Revert "Updated docs about Let's Encrypt" This reverts commit ac26611e05928c7edff3c2a4a66e06977d7165f1. --- doc/SSL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/SSL.md b/doc/SSL.md index bcff929fe5..a72eec2a16 100644 --- a/doc/SSL.md +++ b/doc/SSL.md @@ -90,8 +90,8 @@ If you run your own server, upload the files and check out the Mozilla wiki link Let's encrypt --- -If you run your own server, the "Let's encrypt" initiative might become an interesting alternative. -Their offer is in public beta right now. +If you run your own server and you control your name server, the "Let's encrypt" initiative might become an interesting alternative. +Their offer is not ready, yet. Check out [their website](https://letsencrypt.org/) for status updates. Web server settings From 4961fb3a45b31f6428a34d66bb817bf7fb473866 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Tue, 26 Jul 2016 22:10:13 +0200 Subject: [PATCH 003/391] Unused indexes removed, queries changed --- include/Contact.php | 57 +++++++++++++++++++++++------------------ include/dba.php | 2 ++ include/dbstructure.php | 15 ++++++----- include/onepoll.php | 5 ++-- mod/contacts.php | 11 +------- mod/follow.php | 4 +-- mod/item.php | 2 +- mod/network.php | 9 +++---- mod/nodeinfo.php | 20 ++++++++++++--- 9 files changed, 69 insertions(+), 56 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index 9d69a81a4e..0bc7ca0a48 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -599,57 +599,64 @@ function posts_from_gcontact($a, $gcontact_id) { return $o; } - /** - * @brief Returns posts from a given contact + * @brief Returns posts from a given contact url * * @param App $a argv application class - * @param int $contact_id contact + * @param int $contact_url Contact URL * * @return string posts in HTML */ -function posts_from_contact($a, $contact_id) { +function posts_from_contact_url($a, $contact_url) { require_once('include/conversation.php'); - $r = q("SELECT `url` FROM `contact` WHERE `id` = %d", intval($contact_id)); - if (!$r) - return false; + // There are no posts with "uid = 0" with connector networks + // This speeds up the query a lot + $r = q("SELECT `network`, `id` AS `author-id` FROM `contact` + WHERE `contact`.`nurl` = '%s' AND `contact`.`uid` = 0", + dbesc(normalise_link($contact_url))); + if (in_array($r[0]["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS, ""))) + $sql = "(`item`.`uid` = 0 OR (`item`.`uid` = %d AND `item`.`private`))"; + else + $sql = "`item`.`uid` = %d"; - $contact = $r[0]; + $author_id = intval($r[0]["author-id"]); - if(get_config('system', 'old_pager')) { + if (get_config('system', 'old_pager')) { $r = q("SELECT COUNT(*) AS `total` FROM `item` - WHERE `item`.`uid` = %d AND `author-link` IN ('%s', '%s')", - intval(local_user()), - dbesc(str_replace("https://", "http://", $contact["url"])), - dbesc(str_replace("http://", "https://", $contact["url"]))); + WHERE `author-id` = %d and $sql", + intval($author_id), + intval(local_user())); $a->set_pager_total($r[0]['total']); } - $r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`, +/* +"SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`, `author-name` AS `name`, `owner-avatar` AS `photo`, `owner-link` AS `url`, `owner-avatar` AS `thumb` - FROM `item` FORCE INDEX (`uid_contactid_id`) - WHERE `item`.`uid` = %d AND `contact-id` = %d - AND `author-link` IN ('%s', '%s') - AND NOT `deleted` AND NOT `moderated` AND `visible` - ORDER BY `item`.`id` DESC LIMIT %d, %d", + FROM `item` FORCE INDEX (`authorid_created`) + WHERE `item`.`author-id` = %d AND $sql + AND NOT `deleted` AND NOT `moderated` AND `visible` + +*/ + + $r = q(item_query()." AND `item`.`author-id` = %d AND ".$sql. + " ORDER BY `item`.`created` DESC LIMIT %d, %d", + intval($author_id), intval(local_user()), - intval($contact_id), - dbesc(str_replace("https://", "http://", $contact["url"])), - dbesc(str_replace("http://", "https://", $contact["url"])), intval($a->pager['start']), intval($a->pager['itemspage']) ); - $o .= conversation($a,$r,'community',false); + $o = conversation($a,$r,'community',false); - if(!get_config('system', 'old_pager')) + if(!get_config('system', 'old_pager')) { $o .= alt_pager($a,count($r)); - else + } else { $o .= paginate($a); + } return $o; } diff --git a/include/dba.php b/include/dba.php index 3484ac6683..a9bd571e72 100644 --- a/include/dba.php +++ b/include/dba.php @@ -65,6 +65,7 @@ class dba { $this->db = @new mysqli($server,$user,$pass,$db); if(! mysqli_connect_errno()) { $this->connected = true; + //mysqli_set_charset($this->db, 'utf8'); } } else { @@ -72,6 +73,7 @@ class dba { $this->db = mysql_connect($server,$user,$pass); if($this->db && mysql_select_db($db,$this->db)) { $this->connected = true; + //mysql_set_charset('utf8', $this->db); } } if(! $this->connected) { diff --git a/include/dbstructure.php b/include/dbstructure.php index bd35d0974a..5b1ffc3309 100644 --- a/include/dbstructure.php +++ b/include/dbstructure.php @@ -852,19 +852,19 @@ function db_definition() { "uid_created" => array("uid","created"), "uid_unseen_contactid" => array("uid","unseen","contact-id"), "uid_network_received" => array("uid","network","received"), - "uid_received" => array("uid","received"), - "uid_network_commented" => array("uid","network","commented"), - "uid_commented" => array("uid","commented"), + //"uid_received" => array("uid","received"), + //"uid_network_commented" => array("uid","network","commented"), + //"uid_commented" => array("uid","commented"), "uid_title" => array("uid","title"), "uid_thrparent" => array("uid","thr-parent"), "uid_parenturi" => array("uid","parent-uri"), "uid_contactid_id" => array("uid","contact-id","id"), - "uid_contactid_created" => array("uid","contact-id","created"), + //"uid_contactid_created" => array("uid","contact-id","created"), "gcontactid_uid_created" => array("gcontact-id","uid","created"), "authorid_created" => array("author-id","created"), "ownerid_created" => array("owner-id","created"), - "wall_body" => array("wall","body(6)"), - "uid_visible_moderated_created" => array("uid","visible","moderated","created"), + //"wall_body" => array("wall","body(6)"), + //"uid_visible_moderated_created" => array("uid","visible","moderated","created"), "uid_uri" => array("uid","uri"), "uid_wall_created" => array("uid","wall","created"), "resource-id" => array("resource-id"), @@ -873,7 +873,8 @@ function db_definition() { "contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"), "uid_wall_parent_created" => array("uid","wall","parent","created"), "uid_type_changed" => array("uid","type","changed"), - "contactid_verb" => array("contact-id","verb"), + //"contactid_verb" => array("contact-id","verb"), + "contactid" => array("contact-id"), "deleted_changed" => array("deleted","changed"), "uid_wall_changed" => array("uid","wall","changed"), "uid_eventid" => array("uid","event-id"), diff --git a/include/onepoll.php b/include/onepoll.php index eb1045de14..12bae166dc 100644 --- a/include/onepoll.php +++ b/include/onepoll.php @@ -476,9 +476,10 @@ function onepoll_run(&$argv, &$argc){ // If it seems to be a reply but a header couldn't be found take the last message with matching subject if(!x($datarray,'parent-uri') and $reply) { - $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d ORDER BY `created` DESC LIMIT 1", + $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d AND `network` = '%s' ORDER BY `created` DESC LIMIT 1", dbesc(protect_sprintf($datarray['title'])), - intval($importer_uid)); + intval($importer_uid), + dbesc(NETWORK_MAIL)); if(count($r)) $datarray['parent-uri'] = $r[0]['parent-uri']; } diff --git a/mod/contacts.php b/mod/contacts.php index 4eb435fc75..044cc65107 100644 --- a/mod/contacts.php +++ b/mod/contacts.php @@ -887,16 +887,7 @@ function contact_posts($a, $contact_id) { $o .= $tab_str; - $r = q("SELECT `id` FROM `item` WHERE `contact-id` = %d LIMIT 1", intval($contact_id)); - if ($r) - $o .= posts_from_contact($a, $contact_id); - elseif ($contact["url"]) { - $r = q("SELECT `id` FROM `gcontact` WHERE `nurl` = '%s' LIMIT 1", - dbesc(normalise_link($contact["url"]))); - - if ($r[0]["id"] <> 0) - $o .= posts_from_gcontact($a, $r[0]["id"]); - } + $o .= posts_from_contact_url($a, $contact["url"]); return $o; } diff --git a/mod/follow.php b/mod/follow.php index b92a0d980f..1f56caea50 100644 --- a/mod/follow.php +++ b/mod/follow.php @@ -137,13 +137,13 @@ function follow_content(&$a) { $a->page['aside'] = ""; profile_load($a, "", 0, get_contact_details_by_url($ret["url"])); - // Show last public posts if ($gcontact_id <> 0) { $o .= replace_macros(get_markup_template('section_title.tpl'), array('$title' => t('Status Messages and Posts') )); - $o .= posts_from_gcontact($a, $gcontact_id); + // Show last public posts + $o .= posts_from_contact_url($a, $ret["url"]); } return $o; diff --git a/mod/item.php b/mod/item.php index 6f5f8fc1ea..963912800f 100644 --- a/mod/item.php +++ b/mod/item.php @@ -1032,7 +1032,7 @@ function item_post(&$a) { // Currently the only realistic fixes are to use a reliable server - which precludes shared hosting, // or cut back on plugins which do remote deliveries. - proc_run('php', "include/notifier.php", $notify_type, "$post_id"); + proc_run('php', "include/notifier.php", $notify_type, $post_id); logger('post_complete'); diff --git a/mod/network.php b/mod/network.php index 6ebedbcae8..f62799f768 100644 --- a/mod/network.php +++ b/mod/network.php @@ -577,8 +577,8 @@ function network_content(&$a, $update = 0) { $sql_extra = sprintf(" AND MATCH (`item`.`body`, `item`.`title`) AGAINST ('%s' in boolean mode) ", dbesc(protect_sprintf($search))); else $sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search)))); - $sql_order = "`item`.`received`"; - $order_mode = "received"; + $sql_order = "`item`.`id`"; + $order_mode = "id"; } } if(strlen($file)) { @@ -596,8 +596,7 @@ function network_content(&$a, $update = 0) { // only setup pagination on initial page view $pager_sql = ''; - } - else { + } else { if(get_config('system', 'old_pager')) { $r = q("SELECT COUNT(*) AS `total` FROM $sql_table $sql_post_table INNER JOIN `contact` ON `contact`.`id` = $sql_table.`contact-id` @@ -636,7 +635,7 @@ function network_content(&$a, $update = 0) { $simple_update = (($update) ? " AND `item`.`unseen` " : ''); if ($sql_order == "") - $sql_order = "`item`.`received`"; + $sql_order = "`item`.`id`"; // "New Item View" - show all items unthreaded in reverse created date order $items = q("SELECT %s FROM $sql_table $sql_post_table %s diff --git a/mod/nodeinfo.php b/mod/nodeinfo.php index ba310a1051..b90e05174e 100644 --- a/mod/nodeinfo.php +++ b/mod/nodeinfo.php @@ -174,7 +174,7 @@ function nodeinfo_cron() { return; $last = get_config('nodeinfo','last_calucation'); - +/* if($last) { // Calculate every 24 hours $next = $last + (24 * 60 * 60); @@ -183,7 +183,7 @@ function nodeinfo_cron() { return; } } - logger("cron_start"); +*/ logger("cron_start"); $users = q("SELECT profile.*, `user`.`login_date`, `lastitem`.`lastitem_date` FROM (SELECT MAX(`item`.`changed`) as `lastitem_date`, `item`.`uid` @@ -224,12 +224,24 @@ function nodeinfo_cron() { set_config('nodeinfo','active_users_monthly', $active_users_monthly); } - //$posts = q("SELECT COUNT(*) AS local_posts FROM `item` WHERE `wall` AND `uid` != 0 AND `id` = `parent` AND left(body, 6) != '[share'"); +// $posts = q("SELECT COUNT(*) AS `local_posts` FROM `thread` +// INNER JOIN `contact` ON `contact`.`id` = `thread`.`contact-id` AND `contact`.`uid` = `thread`.`uid` +// WHERE `contact`.`self`"); + $posts = q("SELECT COUNT(*) AS local_posts FROM `thread` WHERE `thread`.`wall`"); +/* + $posts = q("SELECT COUNT(*) AS local_posts FROM `thread` + INNER JOIN `item` ON `item`.`id` = `thread`.`iid` + WHERE `thread`.`wall` AND NOT `thread`.`private` AND + `thread`.`uid` != 0 AND LEFT(`item`.`body`, 6) != '[share' AND + `thread`.`network` IN ('%s', '%s', '%s')", + dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN)); +*/ +/* $posts = q("SELECT COUNT(*) AS `local_posts` FROM `item` INNER JOIN `contact` ON `contact`.`id` = `item`.`contact-id` WHERE `contact`.`self` and `item`.`id` = `item`.`parent` AND left(body, 6) != '[share' AND `item`.`network` IN ('%s', '%s', '%s')", dbesc(NETWORK_OSTATUS), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_DFRN)); - +*/ if (!is_array($posts)) $local_posts = -1; else From d7d698bef4bc0487ae41b61f178f1db18230481b Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Wed, 10 Aug 2016 23:56:17 +0200 Subject: [PATCH 004/391] new API calls for private messsages in Win10 app new API calls used for Windows 10 app (similar calls to existing but extended to include seen id and parent-uri) --- include/api.php | 383 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+) diff --git a/include/api.php b/include/api.php index a856b747f8..8b8ec4c6f5 100644 --- a/include/api.php +++ b/include/api.php @@ -3664,6 +3664,389 @@ api_register_func('api/friendica/notification', 'api_friendica_notification', true, API_METHOD_GET); + /** + * @brief same as api_format_messages, but output extended by seen and parent-uri as needed + * in Windows 10 client + * + * @param array $item + * @param array $recipient + * @param array $sender + * @return array $ret + */ + function api_format_messages_win($item, $recipient, $sender) { + // standard meta information + $ret=Array( + 'id' => $item['id'], + 'sender_id' => $sender['id'] , + 'text' => "", + 'recipient_id' => $recipient['id'], + 'created_at' => api_date($item['created']), + 'sender_screen_name' => $sender['screen_name'], + 'recipient_screen_name' => $recipient['screen_name'], + 'sender' => $sender, + 'recipient' => $recipient, + 'title' => "", + 'seen' => $item['seen'], + 'parent_uri' => $item['parent-uri'], + ); + + // "uid" and "self" are only needed for some internal stuff, so remove it from here + unset($ret["sender"]["uid"]); + unset($ret["sender"]["self"]); + unset($ret["recipient"]["uid"]); + unset($ret["recipient"]["self"]); + + //don't send title to regular StatusNET requests to avoid confusing these apps + if (x($_GET, 'getText')) { + $ret['title'] = $item['title'] ; + if ($_GET["getText"] == "html") { + $ret['text'] = bbcode($item['body'], false, false); + } + elseif ($_GET["getText"] == "plain") { + $ret['text'] = trim(html2plain(bbcode(api_clean_plain_items($item['body']), false, false, 2, true), 0)); + } + } + else { + $ret['text'] = $item['title']."\n".html2plain(bbcode(api_clean_plain_items($item['body']), false, false, 2, true), 0); + } + if (isset($_GET["getUserObjects"]) && $_GET["getUserObjects"] == "false") { + unset($ret['sender']); + unset($ret['recipient']); + } + + return $ret; + } + + /** + * @brief return direct_messages for Windows 10 App (similar to direct_messages/all, but seen + * and parent-uri added to output + * + * @param App $a + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string + */ + function api_friendica_direct_messages_all($type){ + $a = get_app(); + + if (api_user()===false) throw new ForbiddenException(); + + // params + $count = (x($_GET,'count')?$_GET['count']:20); + $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); + if ($page<0) $page=0; + + $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); + $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); + + $user_id = (x($_REQUEST,'user_id')?$_REQUEST['user_id']:""); + $screen_name = (x($_REQUEST,'screen_name')?$_REQUEST['screen_name']:""); + + // caller user info + unset($_REQUEST["user_id"]); + unset($_GET["user_id"]); + + unset($_REQUEST["screen_name"]); + unset($_GET["screen_name"]); + + $user_info = api_get_user($a); + $profile_url = $user_info["url"]; + + // pagination + $start = $page*$count; + + // filters + $sql_extra = "true"; + + if ($max_id > 0) + $sql_extra .= ' AND `mail`.`id` <= '.intval($max_id); + + if ($user_id !="") { + $sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id); + } + elseif($screen_name !=""){ + $sql_extra .= " AND `contact`.`nick` = '" . dbesc($screen_name). "'"; + } + + $r = q("SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid`=%d AND $sql_extra AND `mail`.`id` > %d ORDER BY `mail`.`id` DESC LIMIT %d,%d", + intval(api_user()), + intval($since_id), + intval($start), intval($count) + ); + + // stop execution and return error message if no mails available + if($r == null) { + $answer = array('result' => 'error', 'message' => 'no mails available'); + return api_format_data("direct_messages_all", $type, array('$result' => $answer)); + } + + $ret = Array(); + foreach($r as $item) { + if ($box == "inbox" || $item['from-url'] != $profile_url){ + $recipient = $user_info; + $sender = api_get_user($a,normalise_link($item['contact-url'])); + } + elseif ($box == "sentbox" || $item['from-url'] == $profile_url){ + $recipient = api_get_user($a,normalise_link($item['contact-url'])); + $sender = $user_info; + + } + $ret[]=api_format_messages_win($item, $recipient, $sender); + } + + + $data = array('$messages' => $ret); + switch($type){ + case "atom": + case "rss": + $data = api_rss_extra($a, $data, $user_info); + } + + return api_format_data("direct_messages_all", $type, $data); + + } + api_register_func('api/friendica/direct_messages_all', 'api_friendica_direct_messages_all', true); + + + /** + * @brief update a direct_message to seen state for Windows 10 App + * + * @param App $a + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string + */ + function api_friendica_direct_messages_setseen($type){ + $a = get_app(); + if (api_user()===false) throw new ForbiddenException(); + + // params + $user_info = api_get_user($a); + $uid = $user_info['uid']; + $id = (x($_REQUEST, 'id') ? $_REQUEST['id'] : 0); + + // return error if id is zero + if ($id == "") { + $answer = array('result' => 'error', 'message' => 'message id not specified'); + return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); + } + + // get data of the specified message id + $r = q("SELECT * FROM `mail` WHERE `id` = %d AND `uid` = %d", + intval($id), + intval($uid)); + // error message if specified id is not in database + if (count($r) == 0) { + $answer = array('result' => 'error', 'message' => 'message id not in database'); + return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); + } + + // update seen indicator + $result = q("UPDATE `mail` SET `seen` = 1 WHERE `id` = %d AND `uid` = %d", + intval($id), + intval($uid)); + + if ($result) { + // return success + $answer = array('result' => 'ok', 'message' => 'message set to seen'); + return api_format_data("direct_message_setseen", $type, array('$result' => $answer)); + } else { + $answer = array('result' => 'error', 'message' => 'unknown error'); + return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); + } + } + api_register_func('api/friendica/direct_messages_setseen', 'api_friendica_direct_messages_setseen', true); + + + /** + * @brief delete a direct_message from mail table through api + * + * @param App $a + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string + */ + function api_friendica_direct_messages_delete($type){ + $a = get_app(); + + if (api_user()===false) throw new ForbiddenException(); + + // params + $user_info = api_get_user($a); + $id = (x($_REQUEST,'id') ? $_REQUEST['id'] : 0); + $parenturi = (x($_REQUEST, 'parenturi') ? $_REQUEST['parenturi'] : ""); + $uid = $user_info['uid']; + + // error if no id or parenturi specified + if ($id == 0 || $parenturi == "") { + $answer = array('result' => 'error', 'message' => 'message id or parenturi not specified'); + return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + } + + // get data of the specified message id + $r = q("SELECT * FROM `mail` WHERE `uid` = %d AND `id` = %d", + intval($uid), + intval($id)); + // error message if specified id is not in database + if (count($r) == 0) { + $answer = array('result' => 'error', 'message' => 'message id not in database'); + return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + } + + // delete message + $result = q("DELETE FROM `mail` WHERE `uid` = %d AND `id` = %d AND `parent-uri` = '%s'", + intval($uid), + intval($id), + dbesc($parenturi)); + + if ($result) { + // return success + $answer = array('result' => 'ok', 'message' => 'message deleted'); + return api_format_data("direct_message_delete", $type, array('$result' => $answer)); + } + else { + $answer = array('result' => 'error', 'message' => 'unknown error'); + return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + } + } + api_register_func('api/friendica/direct_messages_delete', 'api_friendica_direct_messages_delete', true); + + + /** + * @brief search for direct_messages containing a searchstring through api + * + * @param App $a + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string + */ + function api_friendica_direct_messages_search($type){ + $a = get_app(); + + if (api_user()===false) throw new ForbiddenException(); + + // params + $user_info = api_get_user($a); + $searchstring = (x($_REQUEST,'searchstring') ? $_REQUEST['searchstring'] : ""); + $uid = $user_info['uid']; + + // error if no searchstring specified + if ($searchstring == "") { + $answer = array('result' => 'error', 'message' => 'searchstring not specified'); + return api_format_data("direct_messages_search", $type, array('$result' => $answer)); + } + + // get data for the specified searchstring + $r = q("SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid`=%d AND `body` LIKE '%s' ORDER BY `mail`.`id` DESC", + intval($uid), + dbesc('%'.$searchstring.'%') + ); + + $profile_url = $user_info["url"]; + // message if nothing was found + if (count($r) == 0) + $success = array('success' => false, 'search_results' => 'nothing found'); + else { + $ret = Array(); + foreach($r as $item) { + if ($box == "inbox" || $item['from-url'] != $profile_url){ + $recipient = $user_info; + $sender = api_get_user($a,normalise_link($item['contact-url'])); + } + elseif ($box == "sentbox" || $item['from-url'] == $profile_url){ + $recipient = api_get_user($a,normalise_link($item['contact-url'])); + $sender = $user_info; + } + $ret[]=api_format_messages_win($item, $recipient, $sender); + } + $success = array('success' => true, 'search_results' => $ret); + } + + return api_format_data("direct_message_search", $type, array('$result' => $success)); + } + api_register_func('api/friendica/direct_messages_search', 'api_friendica_direct_messages_search', true); + + + /** + * @brief returns all messages for a specified parenturi, similar to api/direct_messages/conversation but enhanced to return parenturi and seen state + * + * @param App $a + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string + */ + function api_friendica_direct_messages_conversation($type) { + $a = get_app(); + if (api_user()===false) return false; + + // params + $count = (x($_GET,'count')?$_GET['count']:20); + $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); + if ($page<0) $page=0; + + $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); + $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); + + $user_id = (x($_REQUEST,'user_id')?$_REQUEST['user_id']:""); + $screen_name = (x($_REQUEST,'screen_name')?$_REQUEST['screen_name']:""); + + // caller user info + unset($_REQUEST["user_id"]); + unset($_GET["user_id"]); + + unset($_REQUEST["screen_name"]); + unset($_GET["screen_name"]); + + $user_info = api_get_user($a); + $profile_url = $user_info["url"]; + + + // pagination + $start = $page*$count; + + $sql_extra = "`mail`.`parent-uri`='".dbesc( $_GET["uri"] ) ."'"; + + if ($max_id > 0) + $sql_extra .= ' AND `mail`.`id` <= '.intval($max_id); + + if ($user_id !="") { + $sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id); + } + elseif($screen_name !=""){ + $sql_extra .= " AND `contact`.`nick` = '" . dbesc($screen_name). "'"; + } + + $r = q("SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid`=%d AND $sql_extra AND `mail`.`id` > %d ORDER BY `mail`.`id` DESC LIMIT %d,%d", + intval(api_user()), + intval($since_id), + intval($start), intval($count) + ); + + + $ret = Array(); + foreach($r as $item) { + if ($box == "inbox" || $item['from-url'] != $profile_url){ + $recipient = $user_info; + $sender = api_get_user($a,normalise_link($item['contact-url'])); + } + elseif ($box == "sentbox" || $item['from-url'] == $profile_url){ + $recipient = api_get_user($a,normalise_link($item['contact-url'])); + $sender = $user_info; + + } + $ret[]=api_format_messages_win($item, $recipient, $sender); + } + + + $data = array('$messages' => $ret); + switch($type){ + case "atom": + case "rss": + $data = api_rss_extra($a, $data, $user_info); + } + + return api_format_data("direct_messages", $type, $data); + + } + + api_register_func('api/friendica/direct_messages_conversation','api_friendica_direct_messages_conversation',true); + + /* To.Do: [pagename] => api/1.1/statuses/lookup.json From db6fb8efe262b8142ec74d7132c67241d69b739d Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Thu, 11 Aug 2016 17:34:33 +0200 Subject: [PATCH 005/391] remove api_format_messages_win and include new fields in api_format_messages --- include/api.php | 62 +++++-------------------------------------------- 1 file changed, 6 insertions(+), 56 deletions(-) diff --git a/include/api.php b/include/api.php index 8b8ec4c6f5..c60575638a 100644 --- a/include/api.php +++ b/include/api.php @@ -2049,6 +2049,9 @@ 'recipient_screen_name' => $recipient['screen_name'], 'sender' => $sender, 'recipient' => $recipient, + 'title' => "", + 'friendica_seen' => $item['seen'], + 'friendica_parent_uri' => $item['parent-uri'], ); // "uid" and "self" are only needed for some internal stuff, so remove it from here @@ -3664,59 +3667,6 @@ api_register_func('api/friendica/notification', 'api_friendica_notification', true, API_METHOD_GET); - /** - * @brief same as api_format_messages, but output extended by seen and parent-uri as needed - * in Windows 10 client - * - * @param array $item - * @param array $recipient - * @param array $sender - * @return array $ret - */ - function api_format_messages_win($item, $recipient, $sender) { - // standard meta information - $ret=Array( - 'id' => $item['id'], - 'sender_id' => $sender['id'] , - 'text' => "", - 'recipient_id' => $recipient['id'], - 'created_at' => api_date($item['created']), - 'sender_screen_name' => $sender['screen_name'], - 'recipient_screen_name' => $recipient['screen_name'], - 'sender' => $sender, - 'recipient' => $recipient, - 'title' => "", - 'seen' => $item['seen'], - 'parent_uri' => $item['parent-uri'], - ); - - // "uid" and "self" are only needed for some internal stuff, so remove it from here - unset($ret["sender"]["uid"]); - unset($ret["sender"]["self"]); - unset($ret["recipient"]["uid"]); - unset($ret["recipient"]["self"]); - - //don't send title to regular StatusNET requests to avoid confusing these apps - if (x($_GET, 'getText')) { - $ret['title'] = $item['title'] ; - if ($_GET["getText"] == "html") { - $ret['text'] = bbcode($item['body'], false, false); - } - elseif ($_GET["getText"] == "plain") { - $ret['text'] = trim(html2plain(bbcode(api_clean_plain_items($item['body']), false, false, 2, true), 0)); - } - } - else { - $ret['text'] = $item['title']."\n".html2plain(bbcode(api_clean_plain_items($item['body']), false, false, 2, true), 0); - } - if (isset($_GET["getUserObjects"]) && $_GET["getUserObjects"] == "false") { - unset($ret['sender']); - unset($ret['recipient']); - } - - return $ret; - } - /** * @brief return direct_messages for Windows 10 App (similar to direct_messages/all, but seen * and parent-uri added to output @@ -3790,7 +3740,7 @@ $sender = $user_info; } - $ret[]=api_format_messages_win($item, $recipient, $sender); + $ret[]=api_format_messages($item, $recipient, $sender); } @@ -3953,7 +3903,7 @@ $recipient = api_get_user($a,normalise_link($item['contact-url'])); $sender = $user_info; } - $ret[]=api_format_messages_win($item, $recipient, $sender); + $ret[]=api_format_messages($item, $recipient, $sender); } $success = array('success' => true, 'search_results' => $ret); } @@ -4029,7 +3979,7 @@ $sender = $user_info; } - $ret[]=api_format_messages_win($item, $recipient, $sender); + $ret[]=api_format_messages($item, $recipient, $sender); } From fb087ce89eba07836bfb5fb192b2b1e31e468e62 Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Thu, 11 Aug 2016 23:53:00 +0200 Subject: [PATCH 006/391] Removing api_friendica_direct_messages_conversations due to implementing 'seen' and 'parent-uri' into standard api_format_messages() this call is not needed anymore. Adapting comment blocks. --- include/api.php | 108 +++++------------------------------------------- 1 file changed, 11 insertions(+), 97 deletions(-) diff --git a/include/api.php b/include/api.php index c60575638a..fdaf50e661 100644 --- a/include/api.php +++ b/include/api.php @@ -3668,12 +3668,11 @@ /** - * @brief return direct_messages for Windows 10 App (similar to direct_messages/all, but seen - * and parent-uri added to output + * @brief return direct_messages (similar to direct_messages/all, but additional + * error string returned if no mails available to react in client with notification) * - * @param App $a * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string + * @return string (error -> No Mails available, success -> return messages) */ function api_friendica_direct_messages_all($type){ $a = get_app(); @@ -3744,25 +3743,24 @@ } - $data = array('$messages' => $ret); + $data = array('direct-messages' => $ret); switch($type){ case "atom": case "rss": $data = api_rss_extra($a, $data, $user_info); } - return api_format_data("direct_messages_all", $type, $data); + return api_format_data("direct-messages", $type, $data); } api_register_func('api/friendica/direct_messages_all', 'api_friendica_direct_messages_all', true); /** - * @brief update a direct_message to seen state for Windows 10 App + * @brief update a direct_message to seen state * - * @param App $a * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string + * @return string (success result=ok, error result=error with error message) */ function api_friendica_direct_messages_setseen($type){ $a = get_app(); @@ -3809,9 +3807,8 @@ /** * @brief delete a direct_message from mail table through api * - * @param App $a * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string + * @return string (success result=ok, error result=error with error message) */ function api_friendica_direct_messages_delete($type){ $a = get_app(); @@ -3862,9 +3859,10 @@ /** * @brief search for direct_messages containing a searchstring through api * - * @param App $a * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string + * @return string (success: success=true if found and search_result contains found messages + * success=false if nothing was found, search_result='nothing found', + * error: result=error with error message) */ function api_friendica_direct_messages_search($type){ $a = get_app(); @@ -3913,90 +3911,6 @@ api_register_func('api/friendica/direct_messages_search', 'api_friendica_direct_messages_search', true); - /** - * @brief returns all messages for a specified parenturi, similar to api/direct_messages/conversation but enhanced to return parenturi and seen state - * - * @param App $a - * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string - */ - function api_friendica_direct_messages_conversation($type) { - $a = get_app(); - if (api_user()===false) return false; - - // params - $count = (x($_GET,'count')?$_GET['count']:20); - $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); - if ($page<0) $page=0; - - $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); - $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); - - $user_id = (x($_REQUEST,'user_id')?$_REQUEST['user_id']:""); - $screen_name = (x($_REQUEST,'screen_name')?$_REQUEST['screen_name']:""); - - // caller user info - unset($_REQUEST["user_id"]); - unset($_GET["user_id"]); - - unset($_REQUEST["screen_name"]); - unset($_GET["screen_name"]); - - $user_info = api_get_user($a); - $profile_url = $user_info["url"]; - - - // pagination - $start = $page*$count; - - $sql_extra = "`mail`.`parent-uri`='".dbesc( $_GET["uri"] ) ."'"; - - if ($max_id > 0) - $sql_extra .= ' AND `mail`.`id` <= '.intval($max_id); - - if ($user_id !="") { - $sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id); - } - elseif($screen_name !=""){ - $sql_extra .= " AND `contact`.`nick` = '" . dbesc($screen_name). "'"; - } - - $r = q("SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid`=%d AND $sql_extra AND `mail`.`id` > %d ORDER BY `mail`.`id` DESC LIMIT %d,%d", - intval(api_user()), - intval($since_id), - intval($start), intval($count) - ); - - - $ret = Array(); - foreach($r as $item) { - if ($box == "inbox" || $item['from-url'] != $profile_url){ - $recipient = $user_info; - $sender = api_get_user($a,normalise_link($item['contact-url'])); - } - elseif ($box == "sentbox" || $item['from-url'] == $profile_url){ - $recipient = api_get_user($a,normalise_link($item['contact-url'])); - $sender = $user_info; - - } - $ret[]=api_format_messages($item, $recipient, $sender); - } - - - $data = array('$messages' => $ret); - switch($type){ - case "atom": - case "rss": - $data = api_rss_extra($a, $data, $user_info); - } - - return api_format_data("direct_messages", $type, $data); - - } - - api_register_func('api/friendica/direct_messages_conversation','api_friendica_direct_messages_conversation',true); - - /* To.Do: [pagename] => api/1.1/statuses/lookup.json From 41c1f71d4d609e0db38494b9cc8f319b3aa1b8ce Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Fri, 12 Aug 2016 15:40:22 +0200 Subject: [PATCH 007/391] remove api_friendica_direct_messages_all instead included 'friendica_verbose' parameter into standard function api_direct_messages_box() --- include/api.php | 111 +++++++----------------------------------------- 1 file changed, 16 insertions(+), 95 deletions(-) diff --git a/include/api.php b/include/api.php index fdaf50e661..df93c2aefb 100644 --- a/include/api.php +++ b/include/api.php @@ -2808,7 +2808,7 @@ } api_register_func('api/direct_messages/new','api_direct_messages_new',true, API_METHOD_POST); - function api_direct_messages_box($type, $box) { + function api_direct_messages_box($type, $box, $verbose) { $a = get_app(); @@ -2868,7 +2868,13 @@ intval($since_id), intval($start), intval($count) ); - + if ($verbose == "true") { + // stop execution and return error message if no mails available + if($r == null) { + $answer = array('result' => 'error', 'message' => 'no mails available'); + return api_format_data("direct_messages_all", $type, array('$result' => $answer)); + } + } $ret = Array(); foreach($r as $item) { @@ -2897,16 +2903,20 @@ } function api_direct_messages_sentbox($type){ - return api_direct_messages_box($type, "sentbox"); + $verbose = (x($_GET,'friendica_verbose')?strtolower($_GET['friendica_verbose']):"false"); + return api_direct_messages_box($type, "sentbox", $verbose); } function api_direct_messages_inbox($type){ - return api_direct_messages_box($type, "inbox"); + $verbose = (x($_GET,'friendica_verbose')?strtolower($_GET['friendica_verbose']):"false"); + return api_direct_messages_box($type, "inbox", $verbose); } function api_direct_messages_all($type){ - return api_direct_messages_box($type, "all"); + $verbose = (x($_GET,'friendica_verbose')?strtolower($_GET['friendica_verbose']):"false"); + return api_direct_messages_box($type, "all", $verbose); } function api_direct_messages_conversation($type){ - return api_direct_messages_box($type, "conversation"); + $verbose = (x($_GET,'friendica_verbose')?strtolower($_GET['friendica_verbose']):"false"); + return api_direct_messages_box($type, "conversation", $verbose); } api_register_func('api/direct_messages/conversation','api_direct_messages_conversation',true); api_register_func('api/direct_messages/all','api_direct_messages_all',true); @@ -3667,95 +3677,6 @@ api_register_func('api/friendica/notification', 'api_friendica_notification', true, API_METHOD_GET); - /** - * @brief return direct_messages (similar to direct_messages/all, but additional - * error string returned if no mails available to react in client with notification) - * - * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string (error -> No Mails available, success -> return messages) - */ - function api_friendica_direct_messages_all($type){ - $a = get_app(); - - if (api_user()===false) throw new ForbiddenException(); - - // params - $count = (x($_GET,'count')?$_GET['count']:20); - $page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0); - if ($page<0) $page=0; - - $since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0); - $max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0); - - $user_id = (x($_REQUEST,'user_id')?$_REQUEST['user_id']:""); - $screen_name = (x($_REQUEST,'screen_name')?$_REQUEST['screen_name']:""); - - // caller user info - unset($_REQUEST["user_id"]); - unset($_GET["user_id"]); - - unset($_REQUEST["screen_name"]); - unset($_GET["screen_name"]); - - $user_info = api_get_user($a); - $profile_url = $user_info["url"]; - - // pagination - $start = $page*$count; - - // filters - $sql_extra = "true"; - - if ($max_id > 0) - $sql_extra .= ' AND `mail`.`id` <= '.intval($max_id); - - if ($user_id !="") { - $sql_extra .= ' AND `mail`.`contact-id` = ' . intval($user_id); - } - elseif($screen_name !=""){ - $sql_extra .= " AND `contact`.`nick` = '" . dbesc($screen_name). "'"; - } - - $r = q("SELECT `mail`.*, `contact`.`nurl` AS `contact-url` FROM `mail`,`contact` WHERE `mail`.`contact-id` = `contact`.`id` AND `mail`.`uid`=%d AND $sql_extra AND `mail`.`id` > %d ORDER BY `mail`.`id` DESC LIMIT %d,%d", - intval(api_user()), - intval($since_id), - intval($start), intval($count) - ); - - // stop execution and return error message if no mails available - if($r == null) { - $answer = array('result' => 'error', 'message' => 'no mails available'); - return api_format_data("direct_messages_all", $type, array('$result' => $answer)); - } - - $ret = Array(); - foreach($r as $item) { - if ($box == "inbox" || $item['from-url'] != $profile_url){ - $recipient = $user_info; - $sender = api_get_user($a,normalise_link($item['contact-url'])); - } - elseif ($box == "sentbox" || $item['from-url'] == $profile_url){ - $recipient = api_get_user($a,normalise_link($item['contact-url'])); - $sender = $user_info; - - } - $ret[]=api_format_messages($item, $recipient, $sender); - } - - - $data = array('direct-messages' => $ret); - switch($type){ - case "atom": - case "rss": - $data = api_rss_extra($a, $data, $user_info); - } - - return api_format_data("direct-messages", $type, $data); - - } - api_register_func('api/friendica/direct_messages_all', 'api_friendica_direct_messages_all', true); - - /** * @brief update a direct_message to seen state * From 3b8db28a4311b57c6a59f3845bc35f740cc0ae09 Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Fri, 12 Aug 2016 18:15:03 +0200 Subject: [PATCH 008/391] Implement api/direct_messages/destroy Twitter compliant call replaces api/friendica/direct_messages_delete; JSON return expected by Twitter API and parameter include_entities not yet implemented --- include/api.php | 123 ++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 50 deletions(-) diff --git a/include/api.php b/include/api.php index df93c2aefb..666bafcec9 100644 --- a/include/api.php +++ b/include/api.php @@ -2808,6 +2808,79 @@ } api_register_func('api/direct_messages/new','api_direct_messages_new',true, API_METHOD_POST); + + /** + * @brief delete a direct_message from mail table through api + * + * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' + * @return string + */ + function api_direct_messages_destroy($type){ + $a = get_app(); + + if (api_user()===false) throw new ForbiddenException(); + + // params + $user_info = api_get_user($a); + //required + $id = (x($_REQUEST,'id') ? $_REQUEST['id'] : 0); + // optional + $parenturi = (x($_REQUEST, 'friendica_parenturi') ? $_REQUEST['friendica_parenturi'] : ""); + $verbose = (x($_GET,'friendica_verbose')?strtolower($_GET['friendica_verbose']):"false"); + // TODO: optional parameter 'include_entities' from Twitter API not yet implemented + + $uid = $user_info['uid']; + // error if no id or parenturi specified (for clients posting parent-uri as well) + if ($verbose == "true") { + if ($id == 0 || $parenturi == "") { + $answer = array('result' => 'error', 'message' => 'message id or parenturi not specified'); + return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + } + } + + // BadRequestException if no id specified (for clients using Twitter API) + if ($id == 0) throw new BadRequestException('Message id not specified'); + + // add parent-uri to sql command if specified by calling app + $sql_extra = ($parenturi != "" ? " AND `parent-uri` = '" . dbesc($parenturi) . "'" : ""); + + // get data of the specified message id + $r = q("SELECT * FROM `mail` WHERE `uid` = %d AND `id` = %d" . $sql_extra, + intval($uid), + intval($id)); + + // error message if specified id is not in database + if (count($r) == 0) { + if ($verbose == "true") { + $answer = array('result' => 'error', 'message' => 'message id not in database'); + return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + } + // TODO: BadRequestException ok for Twitter API clients? + throw new BadRequestException('message id not in database'); + } + + // delete message + $result = q("DELETE FROM `mail` WHERE `uid` = %d AND `id` = %d" . $sql_extra, + intval($uid), + intval($id)); + + if ($verbose == "true") { + if ($result) { + // return success + $answer = array('result' => 'ok', 'message' => 'message deleted'); + return api_format_data("direct_message_delete", $type, array('$result' => $answer)); + } + else { + $answer = array('result' => 'error', 'message' => 'unknown error'); + return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); + } + } + // TODO: return JSON data like Twitter API not yet implemented + + } + api_register_func('api/direct_messages/destroy', 'api_direct_messages_destroy', true, API_METHOD_DELETE); + + function api_direct_messages_box($type, $box, $verbose) { $a = get_app(); @@ -3725,56 +3798,6 @@ api_register_func('api/friendica/direct_messages_setseen', 'api_friendica_direct_messages_setseen', true); - /** - * @brief delete a direct_message from mail table through api - * - * @param string $type Known types are 'atom', 'rss', 'xml' and 'json' - * @return string (success result=ok, error result=error with error message) - */ - function api_friendica_direct_messages_delete($type){ - $a = get_app(); - - if (api_user()===false) throw new ForbiddenException(); - - // params - $user_info = api_get_user($a); - $id = (x($_REQUEST,'id') ? $_REQUEST['id'] : 0); - $parenturi = (x($_REQUEST, 'parenturi') ? $_REQUEST['parenturi'] : ""); - $uid = $user_info['uid']; - - // error if no id or parenturi specified - if ($id == 0 || $parenturi == "") { - $answer = array('result' => 'error', 'message' => 'message id or parenturi not specified'); - return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); - } - - // get data of the specified message id - $r = q("SELECT * FROM `mail` WHERE `uid` = %d AND `id` = %d", - intval($uid), - intval($id)); - // error message if specified id is not in database - if (count($r) == 0) { - $answer = array('result' => 'error', 'message' => 'message id not in database'); - return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); - } - - // delete message - $result = q("DELETE FROM `mail` WHERE `uid` = %d AND `id` = %d AND `parent-uri` = '%s'", - intval($uid), - intval($id), - dbesc($parenturi)); - - if ($result) { - // return success - $answer = array('result' => 'ok', 'message' => 'message deleted'); - return api_format_data("direct_message_delete", $type, array('$result' => $answer)); - } - else { - $answer = array('result' => 'error', 'message' => 'unknown error'); - return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); - } - } - api_register_func('api/friendica/direct_messages_delete', 'api_friendica_direct_messages_delete', true); /** From 23393c05ee47a39bcc69b22a6eb5d199e4dc3888 Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Sat, 13 Aug 2016 13:08:16 +0200 Subject: [PATCH 009/391] improved sql statements for direct_messages calls --- include/api.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/api.php b/include/api.php index 666bafcec9..a380845ed1 100644 --- a/include/api.php +++ b/include/api.php @@ -2827,7 +2827,7 @@ // optional $parenturi = (x($_REQUEST, 'friendica_parenturi') ? $_REQUEST['friendica_parenturi'] : ""); $verbose = (x($_GET,'friendica_verbose')?strtolower($_GET['friendica_verbose']):"false"); - // TODO: optional parameter 'include_entities' from Twitter API not yet implemented + /// @todo optional parameter 'include_entities' from Twitter API not yet implemented $uid = $user_info['uid']; // error if no id or parenturi specified (for clients posting parent-uri as well) @@ -2845,17 +2845,17 @@ $sql_extra = ($parenturi != "" ? " AND `parent-uri` = '" . dbesc($parenturi) . "'" : ""); // get data of the specified message id - $r = q("SELECT * FROM `mail` WHERE `uid` = %d AND `id` = %d" . $sql_extra, + $r = q("SELECT `id` FROM `mail` WHERE `uid` = %d AND `id` = %d" . $sql_extra, intval($uid), intval($id)); // error message if specified id is not in database - if (count($r) == 0) { + if (!dbm::is_result($r)) { if ($verbose == "true") { $answer = array('result' => 'error', 'message' => 'message id not in database'); return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); } - // TODO: BadRequestException ok for Twitter API clients? + /// @todo BadRequestException ok for Twitter API clients? throw new BadRequestException('message id not in database'); } @@ -2875,7 +2875,7 @@ return api_format_data("direct_messages_delete", $type, array('$result' => $answer)); } } - // TODO: return JSON data like Twitter API not yet implemented + /// @todo return JSON data like Twitter API not yet implemented } api_register_func('api/direct_messages/destroy', 'api_direct_messages_destroy', true, API_METHOD_DELETE); @@ -3772,11 +3772,11 @@ } // get data of the specified message id - $r = q("SELECT * FROM `mail` WHERE `id` = %d AND `uid` = %d", + $r = q("SELECT `id` FROM `mail` WHERE `id` = %d AND `uid` = %d", intval($id), intval($uid)); // error message if specified id is not in database - if (count($r) == 0) { + if (!dbm::is_result($r)) { $answer = array('result' => 'error', 'message' => 'message id not in database'); return api_format_data("direct_messages_setseen", $type, array('$result' => $answer)); } From e5874aa34cd546a334023e77ab23c89d1461a5fe Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Sat, 13 Aug 2016 13:19:53 +0200 Subject: [PATCH 010/391] updated api documentation to reflect changes on direct_messages added direct_messages/destroy, friendica/direct_messages_setseen --- doc/api.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/doc/api.md b/doc/api.md index 7d6f440c58..02295a95fe 100644 --- a/doc/api.md +++ b/doc/api.md @@ -104,6 +104,7 @@ Unofficial Twitter command. It shows all direct answers (excluding the original * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" * include_entities: "true" shows entities for pictures and links (Default: false) +* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") #### Unsupported parameters * skip_status @@ -116,6 +117,7 @@ Unofficial Twitter command. It shows all direct answers (excluding the original * since_id: minimal id * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" +* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") --- ### direct_messages/conversation (*; AUTH) @@ -127,6 +129,18 @@ Shows all direct messages of a conversation * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" * uri: URI of the conversation +* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") + +--- +### direct_messages/sent (*; AUTH) +#### Parameters +* count: Items per page (default: 20) +* page: page number +* since_id: minimal id +* max_id: maximum id +* getText: Defines the format of the status field. Can be "html" or "plain" +* include_entities: "true" shows entities for pictures and links (Default: false) +* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") --- ### direct_messages/new (POST,PUT; AUTH) @@ -138,14 +152,22 @@ Shows all direct messages of a conversation * title: Title of the direct message --- -### direct_messages/sent (*; AUTH) +### direct_messages/destroy (POST,DELETE; AUTH) #### Parameters -* count: Items per page (default: 20) -* page: page number -* since_id: minimal id -* max_id: maximum id -* getText: Defines the format of the status field. Can be "html" or "plain" -* include_entities: "true" shows entities for pictures and links (Default: false) +* id: id of the message to be deleted +* include_entities: optional, currently not yet implemented +* friendica_parenturi: optional, can be used for increased safety to delete only intended messages +* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") + +#### Return values + +On success: +* JSON return as defined for Twitter API not yet implemented +* on friendica_verbose=true: JSON return {"result":"ok","message":"message deleted"} + +On error: +HTTP 400 BadRequest +* on friendica_verbose=true: different JSON returns {"result":"error","message":"xyz"} --- ### favorites (*; AUTH) @@ -694,6 +716,33 @@ xml ``` +--- +### friendica/direct_messages_setseen (GET; AUTH) +#### Parameters +* id: id of the message to be updated as seen + +#### Return values + +On success: +* JSON return {"result":"ok","message":"message set to seen"} + +On error: +* different JSON returns {"result":"error","message":"xyz"} + +--- +### friendica/direct_messages_search (GET; AUTH) +#### Parameters +* searchstring: string for which the API call should search as '%searchstring%' in field 'body' of all messages of the authenticated user (caption ignored) + +#### Return values +Returns only tested with JSON, XML might work as well. + +On success: +* JSON return {"success":"true","search_results": array of found messages} +* JSOn return {"success":"false","search_results":"nothing found"} + +On error: +* different JSON returns {"result":"error","message":"searchstring not specified"} --- ## Not Implemented API calls @@ -718,7 +767,6 @@ The following API calls from the Twitter API aren't implemented neither in Frien * statuses/lookup * direct_messages/show * search/tweets -* direct_messages/destroy * friendships/no_retweets/ids * friendships/incoming * friendships/outgoing From 30ecd7cf38d160079d954e976888b7125a3f14ef Mon Sep 17 00:00:00 2001 From: gerhard6380 Date: Sat, 13 Aug 2016 16:14:12 +0200 Subject: [PATCH 011/391] adapted documentation removed reference to Windows 10 app --- doc/api.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/api.md b/doc/api.md index 02295a95fe..0570e8e990 100644 --- a/doc/api.md +++ b/doc/api.md @@ -104,7 +104,7 @@ Unofficial Twitter command. It shows all direct answers (excluding the original * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" * include_entities: "true" shows entities for pictures and links (Default: false) -* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") +* friendica_verbose: "true" enables different error returns (default: "false") #### Unsupported parameters * skip_status @@ -117,7 +117,7 @@ Unofficial Twitter command. It shows all direct answers (excluding the original * since_id: minimal id * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" -* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") +* friendica_verbose: "true" enables different error returns (default: "false") --- ### direct_messages/conversation (*; AUTH) @@ -129,7 +129,7 @@ Shows all direct messages of a conversation * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" * uri: URI of the conversation -* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") +* friendica_verbose: "true" enables different error returns (default: "false") --- ### direct_messages/sent (*; AUTH) @@ -140,7 +140,7 @@ Shows all direct messages of a conversation * max_id: maximum id * getText: Defines the format of the status field. Can be "html" or "plain" * include_entities: "true" shows entities for pictures and links (Default: false) -* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") +* friendica_verbose: "true" enables different error returns (default: "false") --- ### direct_messages/new (POST,PUT; AUTH) @@ -157,7 +157,7 @@ Shows all direct messages of a conversation * id: id of the message to be deleted * include_entities: optional, currently not yet implemented * friendica_parenturi: optional, can be used for increased safety to delete only intended messages -* friendica_verbose: "true" enables different error returns for Windows 10 app (default: "false") +* friendica_verbose: "true" enables different error returns (default: "false") #### Return values From 9653ae98aea5acecc04a3136b2160c9d0949fe1f Mon Sep 17 00:00:00 2001 From: rabuzarus Date: Tue, 23 Aug 2016 16:48:13 +0200 Subject: [PATCH 012/391] frio: resize textareas on typing. --- .../theme/frio/frameworks/autosize/LICENSE.md | 21 ++ .../frio/frameworks/autosize/autosize.js | 262 ++++++++++++++++++ .../frio/frameworks/autosize/autosize.min.js | 6 + .../frio/frameworks/autosize/changelog.md | 79 ++++++ view/theme/frio/frameworks/autosize/readme.md | 35 +++ view/theme/frio/js/filebrowser.js | 4 +- view/theme/frio/js/textedit.js | 8 + view/theme/frio/templates/comment_item.tpl | 2 +- view/theme/frio/templates/contacts-head.tpl | 4 +- view/theme/frio/templates/event_form.tpl | 9 +- view/theme/frio/templates/event_head.tpl | 2 +- view/theme/frio/templates/field_textarea.tpl | 2 +- view/theme/frio/templates/head.tpl | 3 +- view/theme/frio/templates/jot.tpl | 4 +- view/theme/frio/templates/profile_edit.tpl | 8 +- view/theme/frio/templates/prv_message.tpl | 9 +- 16 files changed, 445 insertions(+), 13 deletions(-) create mode 100644 view/theme/frio/frameworks/autosize/LICENSE.md create mode 100644 view/theme/frio/frameworks/autosize/autosize.js create mode 100644 view/theme/frio/frameworks/autosize/autosize.min.js create mode 100644 view/theme/frio/frameworks/autosize/changelog.md create mode 100644 view/theme/frio/frameworks/autosize/readme.md diff --git a/view/theme/frio/frameworks/autosize/LICENSE.md b/view/theme/frio/frameworks/autosize/LICENSE.md new file mode 100644 index 0000000000..2de673bfa0 --- /dev/null +++ b/view/theme/frio/frameworks/autosize/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jack Moore + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/view/theme/frio/frameworks/autosize/autosize.js b/view/theme/frio/frameworks/autosize/autosize.js new file mode 100644 index 0000000000..49b8b0b957 --- /dev/null +++ b/view/theme/frio/frameworks/autosize/autosize.js @@ -0,0 +1,262 @@ +/*! + Autosize 3.0.17 + license: MIT + http://www.jacklmoore.com/autosize +*/ +(function (global, factory) { + if (typeof define === 'function' && define.amd) { + define(['exports', 'module'], factory); + } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') { + factory(exports, module); + } else { + var mod = { + exports: {} + }; + factory(mod.exports, mod); + global.autosize = mod.exports; + } +})(this, function (exports, module) { + 'use strict'; + + var set = typeof Set === 'function' ? new Set() : (function () { + var list = []; + + return { + has: function has(key) { + return Boolean(list.indexOf(key) > -1); + }, + add: function add(key) { + list.push(key); + }, + 'delete': function _delete(key) { + list.splice(list.indexOf(key), 1); + } }; + })(); + + var createEvent = function createEvent(name) { + return new Event(name); + }; + try { + new Event('test'); + } catch (e) { + // IE does not support `new Event()` + createEvent = function (name) { + var evt = document.createEvent('Event'); + evt.initEvent(name, true, false); + return evt; + }; + } + + function assign(ta) { + if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return; + + var heightOffset = null; + var clientWidth = ta.clientWidth; + var cachedHeight = null; + + function init() { + var style = window.getComputedStyle(ta, null); + + if (style.resize === 'vertical') { + ta.style.resize = 'none'; + } else if (style.resize === 'both') { + ta.style.resize = 'horizontal'; + } + + if (style.boxSizing === 'content-box') { + heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom)); + } else { + heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); + } + // Fix when a textarea is not on document body and heightOffset is Not a Number + if (isNaN(heightOffset)) { + heightOffset = 0; + } + + update(); + } + + function changeOverflow(value) { + { + // Chrome/Safari-specific fix: + // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space + // made available by removing the scrollbar. The following forces the necessary text reflow. + var width = ta.style.width; + ta.style.width = '0px'; + // Force reflow: + /* jshint ignore:start */ + ta.offsetWidth; + /* jshint ignore:end */ + ta.style.width = width; + } + + ta.style.overflowY = value; + + resize(); + } + + function getParentOverflows(el) { + var arr = []; + + while (el && el.parentNode && el.parentNode instanceof Element) { + if (el.parentNode.scrollTop) { + arr.push({ + node: el.parentNode, + scrollTop: el.parentNode.scrollTop }); + } + el = el.parentNode; + } + + return arr; + } + + function resize() { + var originalHeight = ta.style.height; + var overflows = getParentOverflows(ta); + var docTop = document.documentElement && document.documentElement.scrollTop; // Needed for Mobile IE (ticket #240) + + ta.style.height = 'auto'; + + var endHeight = ta.scrollHeight + heightOffset; + + if (ta.scrollHeight === 0) { + // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM. + ta.style.height = originalHeight; + return; + } + + ta.style.height = endHeight + 'px'; + + // used to check if an update is actually necessary on window.resize + clientWidth = ta.clientWidth; + + // prevents scroll-position jumping + overflows.forEach(function (el) { + el.node.scrollTop = el.scrollTop; + }); + + if (docTop) { + document.documentElement.scrollTop = docTop; + } + } + + function update() { + resize(); + + var computed = window.getComputedStyle(ta, null); + var computedHeight = Math.round(parseFloat(computed.height)); + var styleHeight = Math.round(parseFloat(ta.style.height)); + + // The computed height not matching the height set via resize indicates that + // the max-height has been exceeded, in which case the overflow should be set to visible. + if (computedHeight !== styleHeight) { + if (computed.overflowY !== 'visible') { + changeOverflow('visible'); + } + } else { + // Normally keep overflow set to hidden, to avoid flash of scrollbar as the textarea expands. + if (computed.overflowY !== 'hidden') { + changeOverflow('hidden'); + } + } + + if (cachedHeight !== computedHeight) { + cachedHeight = computedHeight; + var evt = createEvent('autosize:resized'); + ta.dispatchEvent(evt); + } + } + + var pageResize = function pageResize() { + if (ta.clientWidth !== clientWidth) { + update(); + } + }; + + var destroy = (function (style) { + window.removeEventListener('resize', pageResize, false); + ta.removeEventListener('input', update, false); + ta.removeEventListener('keyup', update, false); + ta.removeEventListener('autosize:destroy', destroy, false); + ta.removeEventListener('autosize:update', update, false); + set['delete'](ta); + + Object.keys(style).forEach(function (key) { + ta.style[key] = style[key]; + }); + }).bind(ta, { + height: ta.style.height, + resize: ta.style.resize, + overflowY: ta.style.overflowY, + overflowX: ta.style.overflowX, + wordWrap: ta.style.wordWrap }); + + ta.addEventListener('autosize:destroy', destroy, false); + + // IE9 does not fire onpropertychange or oninput for deletions, + // so binding to onkeyup to catch most of those events. + // There is no way that I know of to detect something like 'cut' in IE9. + if ('onpropertychange' in ta && 'oninput' in ta) { + ta.addEventListener('keyup', update, false); + } + + window.addEventListener('resize', pageResize, false); + ta.addEventListener('input', update, false); + ta.addEventListener('autosize:update', update, false); + set.add(ta); + ta.style.overflowX = 'hidden'; + ta.style.wordWrap = 'break-word'; + + init(); + } + + function destroy(ta) { + if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; + var evt = createEvent('autosize:destroy'); + ta.dispatchEvent(evt); + } + + function update(ta) { + if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return; + var evt = createEvent('autosize:update'); + ta.dispatchEvent(evt); + } + + var autosize = null; + + // Do nothing in Node.js environment and IE8 (or lower) + if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') { + autosize = function (el) { + return el; + }; + autosize.destroy = function (el) { + return el; + }; + autosize.update = function (el) { + return el; + }; + } else { + autosize = function (el, options) { + if (el) { + Array.prototype.forEach.call(el.length ? el : [el], function (x) { + return assign(x, options); + }); + } + return el; + }; + autosize.destroy = function (el) { + if (el) { + Array.prototype.forEach.call(el.length ? el : [el], destroy); + } + return el; + }; + autosize.update = function (el) { + if (el) { + Array.prototype.forEach.call(el.length ? el : [el], update); + } + return el; + }; + } + + module.exports = autosize; +}); \ No newline at end of file diff --git a/view/theme/frio/frameworks/autosize/autosize.min.js b/view/theme/frio/frameworks/autosize/autosize.min.js new file mode 100644 index 0000000000..2108e9033e --- /dev/null +++ b/view/theme/frio/frameworks/autosize/autosize.min.js @@ -0,0 +1,6 @@ +/*! + Autosize 3.0.17 + license: MIT + http://www.jacklmoore.com/autosize +*/ +!function(e,t){if("function"==typeof define&&define.amd)define(["exports","module"],t);else if("undefined"!=typeof exports&&"undefined"!=typeof module)t(exports,module);else{var n={exports:{}};t(n.exports,n),e.autosize=n.exports}}(this,function(e,t){"use strict";function n(e){function t(){var t=window.getComputedStyle(e,null);"vertical"===t.resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),l="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),isNaN(l)&&(l=0),a()}function n(t){var n=e.style.width;e.style.width="0px",e.offsetWidth,e.style.width=n,e.style.overflowY=t,r()}function o(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}function r(){var t=e.style.height,n=o(e),r=document.documentElement&&document.documentElement.scrollTop;e.style.height="auto";var i=e.scrollHeight+l;return 0===e.scrollHeight?void(e.style.height=t):(e.style.height=i+"px",s=e.clientWidth,n.forEach(function(e){e.node.scrollTop=e.scrollTop}),void(r&&(document.documentElement.scrollTop=r)))}function a(){r();var t=window.getComputedStyle(e,null),o=Math.round(parseFloat(t.height)),i=Math.round(parseFloat(e.style.height));if(o!==i?"visible"!==t.overflowY&&n("visible"):"hidden"!==t.overflowY&&n("hidden"),u!==o){u=o;var a=d("autosize:resized");e.dispatchEvent(a)}}if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!i.has(e)){var l=null,s=e.clientWidth,u=null,c=function(){e.clientWidth!==s&&a()},p=function(t){window.removeEventListener("resize",c,!1),e.removeEventListener("input",a,!1),e.removeEventListener("keyup",a,!1),e.removeEventListener("autosize:destroy",p,!1),e.removeEventListener("autosize:update",a,!1),i["delete"](e),Object.keys(t).forEach(function(n){e.style[n]=t[n]})}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",p,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",a,!1),window.addEventListener("resize",c,!1),e.addEventListener("input",a,!1),e.addEventListener("autosize:update",a,!1),i.add(e),e.style.overflowX="hidden",e.style.wordWrap="break-word",t()}}function o(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName){var t=d("autosize:destroy");e.dispatchEvent(t)}}function r(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName){var t=d("autosize:update");e.dispatchEvent(t)}}var i="function"==typeof Set?new Set:function(){var e=[];return{has:function(t){return Boolean(e.indexOf(t)>-1)},add:function(t){e.push(t)},"delete":function(t){e.splice(e.indexOf(t),1)}}}(),d=function(e){return new Event(e)};try{new Event("test")}catch(a){d=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}var l=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?(l=function(e){return e},l.destroy=function(e){return e},l.update=function(e){return e}):(l=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return n(e,t)}),e},l.destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],o),e},l.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],r),e}),t.exports=l}); \ No newline at end of file diff --git a/view/theme/frio/frameworks/autosize/changelog.md b/view/theme/frio/frameworks/autosize/changelog.md new file mode 100644 index 0000000000..61d73e4ff0 --- /dev/null +++ b/view/theme/frio/frameworks/autosize/changelog.md @@ -0,0 +1,79 @@ +## Changelog + +##### v.3.0.17 - 2016-7-25 +* Fixed Chromium issue where getComputedStyle pixel value did not exactly match the style pixel value. Fixes #306. +* Removed undocumented argument, minor refactoring, more comments. + +##### v.3.0.16 - 2016-7-13 +* Fixed issue with overflowing parent elements. Fixes #298. + +##### v.3.0.15 - 2016-1-26 +* Used newer Event constructor, when available. Fixes #280. + +##### v.3.0.14 - 2015-11-11 +* Fixed memory leak on destroy. Merged #271, fixes #270. +* Fixed bug in old versions of Firefox (1-5), fixes #246. + +##### v.3.0.13 - 2015-09-26 +* Fixed scroll-bar jumpiness in iOS. Merged #261, fixes #207. +* Fixed reflowing of initial text in Chrome and Safari. + +##### v.3.0.12 - 2015-09-14 +* Merged changes were discarded when building new dist files. Merged #255, Fixes #257 for real this time. + +##### v.3.0.11 - 2015-09-14 +* Fixed regression from 3.0.10 that caused an error with ES5 browsers. Merged #255, Fixes #257. + +##### v.3.0.10 - 2015-09-10 +* Removed data attribute as a way of tracking which elements autosize has been assigned to. fixes #254, fixes #200. + +##### v.3.0.9 - 2015-09-02 +* Fixed issue with assigning autosize to detached nodes. Merged #253, Fixes #234. + +##### v.3.0.8 - 2015-06-29 +* Fixed the `autosize:resized` event not being triggered when the overflow changes. Fixes #244. + +##### v.3.0.7 - 2015-06-29 +* Fixed jumpy behavior in Windows 8.1 mobile. Fixes #239. + +##### v.3.0.6 - 2015-05-19 +* Renamed 'dest' folder to 'dist' to follow common conventions. + +##### v.3.0.5 - 2015-05-18 +* Do nothing in Node.js environment. + +##### v.3.0.4 - 2015-05-05 +* Added options object for indicating if the script should set the overflowX and overflowY. The default behavior lets the script control the overflows, which will normalize the appearance between browsers. Fixes #220. + +##### v.3.0.3 - 2015-04-23 +* Avoided adjusting the height for hidden textarea elements. Fixes #155. + +##### v.3.0.2 - 2015-04-23 +* Reworked to respect max-height of any unit-type. Fixes #191. + +##### v.3.0.1 - 2015-04-23 +* Fixed the destroy event so that it removes its own event handler. Fixes #218. + +##### v.3.0.0 - 2015-04-15 +* Added new methods for updating and destroying: + + * autosize.update(elements) + * autosize.destroy(elements) + +* Renamed custom events as to not use jQuery's custom events namespace: + + * autosize.resized renamed to autosize:resized + * autosize.update renamed to autosize:update + * autosize.destroy renamed to autosize:destroy + +##### v.2.0.1 - 2015-04-15 +* Version bump for NPM publishing purposes + +##### v.2.0.0 - 2015-02-25 + +* Smaller, simplier code-base +* New API. Example usage: `autosize(document.querySelectorAll(textarea));` +* Dropped jQuery dependency +* Dropped IE7-IE8 support +* Dropped optional parameters +* Closes #98, closes #106, closes #123, fixes #129, fixes #132, fixes #139, closes #140, closes #166, closes #168, closes #192, closes #193, closes #197 \ No newline at end of file diff --git a/view/theme/frio/frameworks/autosize/readme.md b/view/theme/frio/frameworks/autosize/readme.md new file mode 100644 index 0000000000..385782917d --- /dev/null +++ b/view/theme/frio/frameworks/autosize/readme.md @@ -0,0 +1,35 @@ +## Summary + +Autosize is a small, stand-alone script to automatically adjust textarea height to fit text. + +#### Demo + +Full documentation and a demo can be found at [jacklmoore.com/autosize](http://jacklmoore.com/autosize) + +#### Install via NPM +```bash +npm install autosize +``` + +#### Browser compatibility + +Chrome | Firefox | IE | Safari | iOS Safari | Android | Opera Mini | Windows Phone IE +------ | --------|----|--------|------------|---------|------------|------------------ +yes | yes | 9 | yes | yes | 4 | ? | 8.1 + +#### Usage + +The autosize function accepts a single textarea element, or an array or array-like object (such as a NodeList or jQuery collection) of textarea elements. + +```javascript +// from a NodeList +autosize(document.querySelectorAll('textarea')); + +// from a single Node +autosize(document.querySelector('textarea')); + +// from a jQuery collection +autosize($('textarea')); +``` + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php) diff --git a/view/theme/frio/js/filebrowser.js b/view/theme/frio/js/filebrowser.js index 0fe501d548..768db3a705 100644 --- a/view/theme/frio/js/filebrowser.js +++ b/view/theme/frio/js/filebrowser.js @@ -135,11 +135,13 @@ var FileBrowser = { this.dataset.filename, embed, FileBrowser.id, - this.dataset.img + this.dataset.img, ]); // close model $('#modal').modal('hide'); + // update autosize for this textarea + autosize.update($(".text-autosize")); // if (id!=="") { // commentExpand(FileBrowser.id); // //$("#comment-edit-text-558").empty(); diff --git a/view/theme/frio/js/textedit.js b/view/theme/frio/js/textedit.js index 0b3db0571f..9b36d1569d 100644 --- a/view/theme/frio/js/textedit.js +++ b/view/theme/frio/js/textedit.js @@ -93,6 +93,8 @@ function commentOpenUI(obj, id) { $("#comment-edit-text-" + id).attr('tabindex','9'); $("#comment-edit-submit-" + id).attr('tabindex','10'); $("#comment-edit-submit-wrapper-" + id).show(); + // initiale autosize for this comment + autosize($("#comment-edit-text-" + id + ".text-autosize")); } }; @@ -109,6 +111,8 @@ function commentCloseUI(obj, id) { $("#comment-edit-text-" + id).removeAttr('tabindex'); $("#comment-edit-submit-" + id).removeAttr('tabindex'); $("#comment-edit-submit-wrapper-" + id).hide(); + // destroy the automatic textarea resizing + autosize.destroy($("#comment-edit-text-" + id + ".text-autosize")); } }; @@ -120,6 +124,8 @@ function jotTextOpenUI(obj) { if(obj.value == aStr.share) { obj.value = ''; $(".modal-body #profile-jot-text").addClass("profile-jot-text-full").removeClass("profile-jot-text-empty"); + // initiale autosize for the jot + autosize($(".modal-body #profile-jot-text")); } } @@ -129,6 +135,8 @@ function jotTextCloseUI(obj) { if(obj.value === '') { obj.value = aStr.share; $(".modal-body #profile-jot-text").removeClass("profile-jot-text-full").addClass("profile-jot-text-empty"); + // destroy the automatic textarea resizing + autosize.destroy($(".modal-body #profile-jot-text")); } } diff --git a/view/theme/frio/templates/comment_item.tpl b/view/theme/frio/templates/comment_item.tpl index 116a7b7d4d..405a859642 100644 --- a/view/theme/frio/templates/comment_item.tpl +++ b/view/theme/frio/templates/comment_item.tpl @@ -18,7 +18,7 @@
-->
- +
{{if $qcomment}} +