From 976be81ce994850a358b88cc82b22c09dcb6056f Mon Sep 17 00:00:00 2001 From: Hannes Mannerheim Date: Tue, 25 Aug 2015 23:27:08 +0200 Subject: [PATCH] suggest group mentions, and always post to correct group even user is member of multiple groups with same nickname --- QvitterPlugin.php | 40 +++ actions/apiqvitterallfollowing.php | 83 +++++-- actions/apiqvitterstatusesupdate.php | 356 +++++++++++++++++++++++++++ actions/qvitter.php | 1 + css/qvitter.css | 3 +- img/default-avatar-mini.png | Bin 1535 -> 0 bytes img/default-avatar-profile.png | Bin 9113 -> 0 bytes img/default-avatar-stream.png | Bin 3907 -> 0 bytes js/ajax-functions.js | 6 +- js/dom-functions.js | 9 +- js/misc-functions.js | 24 +- js/qvitter.js | 193 +++++++++++++-- 12 files changed, 652 insertions(+), 63 deletions(-) create mode 100644 actions/apiqvitterstatusesupdate.php delete mode 100755 img/default-avatar-mini.png delete mode 100755 img/default-avatar-profile.png delete mode 100755 img/default-avatar-stream.png diff --git a/QvitterPlugin.php b/QvitterPlugin.php index 645272b..8709129 100644 --- a/QvitterPlugin.php +++ b/QvitterPlugin.php @@ -179,6 +179,10 @@ class QvitterPlugin extends Plugin { array('action' => 'qvitteradminsettings')); $m->connect('main/qlogin', array('action' => 'qvitterlogin')); + URLMapperOverwrite::overwrite_variable($m, 'api/statuses/update.:format', + array('action' => 'ApiStatusesUpdate'), + array('format' => '(xml|json)'), + 'ApiQvitterStatusesUpdate'); // check if we should reroute UI to qvitter, and which home-stream the user wants (hide-replies or normal) @@ -916,6 +920,42 @@ class QvitterPlugin extends Plugin { return true; } + /** + * Correct group mentions + * + * We get the correct group ids in a $_POST var called "post_to_groups", formatted as a string with ids separated by colon, e.g. 4:5 + * + * @return boolean hook flag + */ + public function onEndFindMentions($sender, $text, &$mentions) { + + // get the correct group profiles + if(isset($_POST['post_to_groups'])) { + $correct_group_mentions = explode(':',$_POST['post_to_groups']); + foreach($correct_group_mentions as $group_id) { + $correct_group_mentions_profiles[] = Profile::getKV('id',$group_id); + } + + // loop through the groups guessed by gnu social's common_find_mentions() and correct them + foreach($mentions as $mention_array_id=>$mention) { + foreach($correct_group_mentions_profiles as $correct_group_array_id=>$correct_group_profile) { + if($mention['mentioned'][0]->nickname == $correct_group_profile->nickname + && !isset($mentions[$mention_array_id]['corrected'])) { + $mentions[$mention_array_id]['mentioned'][0] = $correct_group_profile; + $user_group = User_group::getKV('profile_id',$correct_group_profile->id); + $mentions[$mention_array_id]['url'] = $user_group->permalink(); + $mentions[$mention_array_id]['title'] = $user_group->getFancyName(); + $mentions[$mention_array_id]['corrected'] = true; + // now we've used this + unset($correct_group_mentions_profiles[$correct_group_array_id]); + } + } + } + } + + return true; + } + /** diff --git a/actions/apiqvitterallfollowing.php b/actions/apiqvitterallfollowing.php index 9afd07b..9cef1bc 100644 --- a/actions/apiqvitterallfollowing.php +++ b/actions/apiqvitterallfollowing.php @@ -1,11 +1,11 @@ \\\\_\ · - · \\) \____) · + · \\) \____) · + · · · · - · · · Qvitter is free software: you can redistribute it and / or modify it · · under the terms of the GNU Affero General Public License as published by · · the Free Software Foundation, either version three of the License or (at · @@ -36,7 +36,7 @@ · along with Qvitter. If not, see . · · · · Contact h@nnesmannerhe.im if you have any questions. · - · · + · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */ @@ -48,6 +48,7 @@ class ApiQvitterAllFollowingAction extends ApiBareAuthAction var $profiles = null; var $users_stripped = null; + var $groups_stripped = null; /** * Take arguments for running @@ -71,16 +72,16 @@ class ApiQvitterAllFollowingAction extends ApiBareAuthAction } $this->profiles = $this->getProfiles(); + $this->groups = $this->getGroups(); - - // only keep id, name, nickname and avatar URL + + // profiles: only keep id, name, nickname and avatar URL foreach($this->profiles as $p) { try { - $avatar = Avatar::byProfile($p, AVATAR_STREAM_SIZE); - $avatar = $avatar->url; + $avatar = Avatar::urlByProfile($p, AVATAR_STREAM_SIZE); } catch (Exception $e) { $avatar = false; - } + } $this_user = array($p->fullname,$p->nickname,$avatar); if(!$p->isLocal()) { $this_user[3] = $p->getUrl(); @@ -91,6 +92,20 @@ class ApiQvitterAllFollowingAction extends ApiBareAuthAction $this->users_stripped[$p->id] = $this_user; } + // groups: only keep id, name, nickname, avatar and local aliases + foreach($this->groups as $user_group) { + $p = $user_group->getProfile(); + $avatar = $user_group->stream_logo; + $this_group = array($p->fullname,$p->nickname,$avatar); + if(!$user_group->isLocal()) { + $this_group[3] = $p->getUrl(); + } + else { + $this_group[3] = false; + } + $this->groups_stripped[$p->id] = $this_group; + } + return true; } @@ -104,13 +119,13 @@ class ApiQvitterAllFollowingAction extends ApiBareAuthAction protected function handle() { parent::handle(); - + $this->initDocument('json'); - $this->showJsonObjects($this->users_stripped); + $this->showJsonObjects(array('users'=>$this->users_stripped,'groups'=>$this->groups_stripped)); $this->endDocument('json'); } - + /** * Get profiles * @@ -123,16 +138,10 @@ class ApiQvitterAllFollowingAction extends ApiBareAuthAction $subs = null; - if (isset($this->tag)) { - $subs = $this->target->getTaggedSubscriptions( - $this->tag, $offset, $limit - ); - } else { - $subs = $this->target->getSubscribed( - $offset, - $limit - ); - } + $subs = $this->target->getSubscribed( + $offset, + $limit + ); $profiles = array(); @@ -143,4 +152,28 @@ class ApiQvitterAllFollowingAction extends ApiBareAuthAction return $profiles; } + /** + * Get groups + * + * @return array groups + */ + function getGroups() + { + $groups = array(); + + $group = $this->target->getGroups( + ($this->page - 1) * $this->count, + $this->count, + $this->since_id, + $this->max_id + ); + + while ($group->fetch()) { + $groups[] = clone($group); + } + + return $groups; + } + + } diff --git a/actions/apiqvitterstatusesupdate.php b/actions/apiqvitterstatusesupdate.php new file mode 100644 index 0000000..15fb927 --- /dev/null +++ b/actions/apiqvitterstatusesupdate.php @@ -0,0 +1,356 @@ +. + * + * @category API + * @package StatusNet + * @author Craig Andrews + * @author Evan Prodromou + * @author Jeffery To + * @author Tom Blankenship + * @author Mike Cochrane + * @author Robin Millette + * @author Zach Copley + * @copyright 2009-2010 StatusNet, Inc. + * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ + +/* External API usage documentation. Please update when you change how this method works. */ + +/*! @page statusesupdate statuses/update + + @section Description + Updates the authenticating user's status. Requires the status parameter specified below. + Request must be a POST. + + @par URL pattern + /api/statuses/update.:format + + @par Formats (:format) + xml, json + + @par HTTP Method(s) + POST + + @par Requires Authentication + Yes + + @param status (Required) The URL-encoded text of the status update. + @param source (Optional) The source application name, if using HTTP authentication or an anonymous OAuth consumer. + @param in_reply_to_status_id (Optional) The ID of an existing status that the update is in reply to. + @param lat (Optional) The latitude the status refers to. + @param long (Optional) The longitude the status refers to. + @param media (Optional) a media upload, such as an image or movie file. + + @sa @ref authentication + @sa @ref apiroot + + @subsection usagenotes Usage notes + + @li The URL pattern is relative to the @ref apiroot. + @li If the @e source parameter is not supplied the source of the status will default to 'api'. When authenticated via a registered OAuth application, the application's registered name and URL will always override the source parameter. + @li The XML response uses GeoRSS + to encode the latitude and longitude (see example response below ). + @li Data uploaded via the @e media parameter should be multipart/form-data encoded. + + @subsection exampleusage Example usage + + @verbatim + curl -u username:password http://example.com/api/statuses/update.xml -d status='Howdy!' -d lat='30.468' -d long='-94.743' + @endverbatim + + @subsection exampleresponse Example response + + @verbatim + + + Howdy! + false + Tue Mar 30 23:28:05 +0000 2010 + + api + 26668724 + + + + 30.468 -94.743 + + false + + 25803 + Jed Sanders + jedsanders + Hoop and Holler, Texas + I like to think of myself as America's Favorite. + http://avatar.example.com/25803-48-20080924200604.png + http://jedsanders.net + false + 5 + + + + + + 2 + Wed Sep 24 20:04:00 +0000 2008 + 0 + 0 + UTC + + false + 70 + true + true + + + @endverbatim +*/ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Updates the authenticating user's status (posts a notice). + * + * @category API + * @package StatusNet + * @author Craig Andrews + * @author Evan Prodromou + * @author Jeffery To + * @author Tom Blankenship + * @author Mike Cochrane + * @author Robin Millette + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ +class ApiQvitterStatusesUpdateAction extends ApiAuthAction +{ + protected $needPost = true; + + var $status = null; + var $in_reply_to_status_id = null; + var $lat = null; + var $lon = null; + + /** + * Take arguments for running + * + * @param array $args $_REQUEST args + * + * @return boolean success flag + */ + protected function prepare(array $args=array()) + { + parent::prepare($args); + + $this->status = $this->trimmed('status'); + $this->post_to_groups = $this->trimmed('post_to_groups'); + $this->lat = $this->trimmed('lat'); + $this->lon = $this->trimmed('long'); + + $this->in_reply_to_status_id + = intval($this->trimmed('in_reply_to_status_id')); + + return true; + } + + /** + * Handle the request + * + * Make a new notice for the update, save it, and show it + * + * @return void + */ + protected function handle() + { + parent::handle(); + + // Workaround for PHP returning empty $_POST and $_FILES when POST + // length > post_max_size in php.ini + + if (empty($_FILES) + && empty($_POST) + && ($_SERVER['CONTENT_LENGTH'] > 0) + ) { + // TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit. + // TRANS: %s is the number of bytes of the CONTENT_LENGTH. + $msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.', + 'The server was unable to handle that much POST data (%s bytes) due to its current configuration.', + intval($_SERVER['CONTENT_LENGTH'])); + + $this->clientError(sprintf($msg, $_SERVER['CONTENT_LENGTH'])); + } + + if (empty($this->status)) { + // TRANS: Client error displayed when the parameter "status" is missing. + $this->clientError(_('Client must provide a \'status\' parameter with a value.')); + } + + if (is_null($this->scoped)) { + // TRANS: Client error displayed when updating a status for a non-existing user. + $this->clientError(_('No such user.'), 404); + } + + /* Do not call shortenlinks until the whole notice has been build */ + + // Check for commands + + $inter = new CommandInterpreter(); + $cmd = $inter->handle_command($this->auth_user, $this->status); + + if ($cmd) { + if ($this->supported($cmd)) { + $cmd->execute(new Channel()); + } + + // Cmd not supported? Twitter just returns your latest status. + // And, it returns your last status whether the cmd was successful + // or not! + + $this->notice = $this->auth_user->getCurrentNotice(); + } else { + $reply_to = null; + + if (!empty($this->in_reply_to_status_id)) { + // Check whether notice actually exists + + $reply = Notice::getKV($this->in_reply_to_status_id); + + if ($reply) { + $reply_to = $this->in_reply_to_status_id; + } else { + // TRANS: Client error displayed when replying to a non-existing notice. + $this->clientError(_('Parent notice not found.'), 404); + } + } + + $upload = null; + try { + $upload = MediaFile::fromUpload('media', $this->scoped); + $this->status .= ' ' . $upload->shortUrl(); + /* Do not call shortenlinks until the whole notice has been build */ + } catch (NoUploadedMediaException $e) { + // There was no uploaded media for us today. + } + + // in Qvitter we shorten _before_ posting, so disble shortening here + $status_shortened = $this->status; + + if (Notice::contentTooLong($status_shortened)) { + if ($upload instanceof MediaFile) { + $upload->delete(); + } + // TRANS: Client error displayed exceeding the maximum notice length. + // TRANS: %d is the maximum lenth for a notice. + $msg = _m('Maximum notice size is %d character, including attachment URL.', + 'Maximum notice size is %d characters, including attachment URL.', + Notice::maxContent()); + /* Use HTTP 413 error code (Request Entity Too Large) + * instead of basic 400 for better understanding + */ + $this->clientError(sprintf($msg, Notice::maxContent()), 413); + } + + + $content = html_entity_decode($status_shortened, ENT_NOQUOTES, 'UTF-8'); + + // groups + $group_ids = Array(); + if(strlen($this->post_to_groups)>0) { + $groups_profile_ids = explode(':',$this->post_to_groups); + foreach($groups_profile_ids as $group_profile_id) { + $user_group = User_group::getKV('profile_id',$group_profile_id); + $group_ids[] = $user_group->id; + } + } + + $options = array('reply_to' => $reply_to, 'groups' => $group_ids); + + if ($this->scoped->shareLocation()) { + + $locOptions = Notice::locationOptions($this->lat, + $this->lon, + null, + null, + $this->scoped); + + $options = array_merge($options, $locOptions); + } + + try { + $this->notice = Notice::saveNew( + $this->scoped->id, + $content, + $this->source, + $options + ); + } catch (Exception $e) { + $this->clientError($e->getMessage(), $e->getCode()); + } + + if (isset($upload)) { + $upload->attachToNotice($this->notice); + } + } + + $this->showNotice(); + } + + /** + * Show the resulting notice + * + * @return void + */ + function showNotice() + { + if (!empty($this->notice)) { + if ($this->format == 'xml') { + $this->showSingleXmlStatus($this->notice); + } elseif ($this->format == 'json') { + $this->show_single_json_status($this->notice); + } + } + } + + /** + * Is this command supported when doing an update from the API? + * + * @param string $cmd the command to check for + * + * @return boolean true or false + */ + function supported($cmd) + { + static $cmdlist = array('SubCommand', 'UnsubCommand', + 'OnCommand', 'OffCommand', 'JoinCommand', 'LeaveCommand'); + + $supported = null; + + if (Event::handle('CommandSupportedAPI', array($cmd, &$supported))) { + $supported = $supported || in_array(get_class($cmd), $cmdlist); + } + + return $supported; + } +} diff --git a/actions/qvitter.php b/actions/qvitter.php index a3cedf7..87287f0 100644 --- a/actions/qvitter.php +++ b/actions/qvitter.php @@ -195,6 +195,7 @@ class QvitterAction extends ApiAction */ window.defaultAvatarStreamSize = ; + window.defaultAvatarProfileSize = ; window.textLimit = ; window.registrationsClosed = ; window.thisSiteThinksItIsHttpButIsActuallyHttps = eKDSe#|y?|*3qk@A>;dre^DkOiSwU4*H5wZm z!Hj~Tx3?E9EiEW3D}!cq49UrNF+4Je>1hKN7vErDpbtYMD$LEz@jFXP%kcKTB0YN4 z^qXA(zP|pVrKKebN*9KP@%HUoeqnQS6E9!BLPtj@Qqq!z6=TqmJ&Ub*)%pbHZVRuj={k})YjH<@9j}R z)z^cR00Fyao?D6_A!@piNnU;*tX7=H@x=%AT4RMnSf!t7K3ryQu5| z$YeF>?^i>o({aEZ+ujC@#%GwHdxmP63>B4?$j!@vRC=G1o8c5u58QSEI66A{sZ=V+ zYRh0SOrfx_7*SC%_|%%3nvs%{hK7bltgo;0Ge)Je^BIhdX|cAp#?M~7cmW58Q-1^4 z+S=`BPkVcZZxa)f)QYBh{t}glg9i^2O%wckO-&6*9Z;*)2nYzo)vJEk+S=k2p0Kk) zb+wH6S5u!Jf@Ho6Ak@;z_Gk7vIwme@CtH?{yZd=g*VNP$GBQM@EIAK2KR=JSxOmLX z&T+*>MTenB)eYgjR7xx#BO{}%Dz^{AWqaP&+XH?+7b?V=q9(0Yi|5au6Ymp9O-n^c zNDzt(vXPfxz)NQ`-lirn8PhN#Ha-k(ZLQGjbB)VKT|(y zMn{_*U0sjh?|W zAT>1w^@?H&_!~UEJkZkd0FzIZl>L1SXcUOO6$;n0=lGNl3=Z*oEV-bd8>O@ezurYt zQc`k8O-(K8>gs4Uyd)*Kz|ztR4b4*APKrWg^bKs_36|bzG5xHUfVvPH7s~0QWr+Iv z2DG-eK`2aTDstSj?5>{?tykBP28c35k(dhYqh+MzF9piuG+B zKRbNb6tqQ2y0;iLd{$1Mc5&MS;O`$G9v&WsT&@7E4$zLLfpLUk?oY%ggd;II8n4$h z9Dq3k$SX|a04yn%{o>*xcS_844}hoVWf5yKn^H?lYnYl^AUf_Q-finqaz6t-1NAU2 zsIjm*$^n+&KSuv>Bj}F`mKN41C@ADgGa8Ku3=DGr7?{NJ744s&GBd@+3kwUVtgM3l zNk>l4khU4`p@(`z&Q-&LvMQJ_u4}NeIZl%tf@8Yw5o&OMH`d0q=@h5JW>qdQ3F%BI%iX%sk;lKeCczIo> z>2BMig=oeBX!L(wU0p4rwJf85uCnIl7Fk_geG92c+0>*^$`x{@;)Bco#o0M6J0)eW lr2f@WoJd;l-|zch*k7QN35$~3ENB1#002ovPDHLkV1o0C(O3Wg diff --git a/img/default-avatar-profile.png b/img/default-avatar-profile.png deleted file mode 100755 index 82c20a4fe9596378f1612223b441ab07b76d962e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9113 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

q<&n-LV{q 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 X7f*L97EX|i00000NkvXXu0mjfp7MYC diff --git a/img/default-avatar-stream.png b/img/default-avatar-stream.png deleted file mode 100755 index a3423d8f42af580c7c03de2e9a967c80770e8733..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3907 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 RfhYg~002ovPDHLkV1isfZVdnc diff --git a/js/ajax-functions.js b/js/ajax-functions.js index 41a437f..cd12bfa 100644 --- a/js/ajax-functions.js +++ b/js/ajax-functions.js @@ -293,17 +293,19 @@ function APIJoinOrLeaveGroup(joinOrLeave,group_id,this_element,actionOnSuccess) · · @param queetText_txt: the text to post · @param in_reply_to_status_id: the local id for the queet to reply to + · @param postToGroups: post the queet in these groups, string of ids separated by colon expected, e.g. 5:2:4 · @param actionOnSuccess: callback function, false on error, data on success · · · · · · · · · · · · · · */ -function postQueetToAPI(queetText_txt, in_reply_to_status_id, actionOnSuccess) { +function postQueetToAPI(queetText_txt, in_reply_to_status_id, postToGroups, actionOnSuccess) { $.ajax({ url: window.apiRoot + 'statuses/update.json?t=' + timeNow(), type: "POST", data: { status: queetText_txt, source: 'Qvitter', - in_reply_to_status_id: in_reply_to_status_id + in_reply_to_status_id: in_reply_to_status_id, + post_to_groups: postToGroups }, dataType:"json", error: function(data){ actionOnSuccess(false); console.log(data); }, diff --git a/js/dom-functions.js b/js/dom-functions.js index 5cb7bfb..a74a264 100644 --- a/js/dom-functions.js +++ b/js/dom-functions.js @@ -446,9 +446,9 @@ function groupProfileCard(groupAlias) { data.nickname = data.nickname || ''; data.fullname = data.fullname || ''; - data.stream_logo = data.stream_logo || window.fullUrlToThisQvitterApp + 'img/default-avatar-stream.png'; - data.homepage_logo = data.homepage_logo || window.fullUrlToThisQvitterApp + 'img/default-avatar-profile.png'; - data.original_logo = data.original_logo || window.fullUrlToThisQvitterApp + 'img/default-avatar-profile.png'; + data.stream_logo = data.stream_logo || window.defaultAvatarStreamSize; + data.homepage_logo = data.homepage_logo || window.defaultAvatarProfileSize; + data.original_logo = data.original_logo || window.defaultAvatarProfileSize; data.description = data.description || ''; data.homepage = data.homepage || ''; data.url = data.url || ''; @@ -1718,7 +1718,7 @@ function addToFeed(feed, after, extraClasses, isReply) { if($('#stream-item-' + obj.id).length == 0) { obj.description = obj.description || ''; - obj.stream_logo = obj.stream_logo || window.fullUrlToThisQvitterApp + 'img/default-avatar-profile.png'; + obj.stream_logo = obj.stream_logo || window.defaultAvatarStreamSize; // rtl or not var rtlOrNot = ''; @@ -1733,7 +1733,6 @@ function addToFeed(feed, after, extraClasses, isReply) { } var memberButton = ''; if(typeof window.loggedIn.screen_name != 'undefined') { - console.log(obj); var memberButton = '

'; } var groupAvatar = obj.stream_logo; diff --git a/js/misc-functions.js b/js/misc-functions.js index 844f5dd..9eebb73 100644 --- a/js/misc-functions.js +++ b/js/misc-functions.js @@ -225,16 +225,28 @@ function checkLocalStorage() { function cacheSyntaxHighlighting() { - // regexps for syntax highlighting - var allDomains = '(abb|abbott|abogado|ac|academy|accenture|accountant|accountants|active|actor|ad|ads|adult|ae|aero|af|afl|ag|agency|ai|aig|airforce|al|allfinanz|alsace|am|amsterdam|an|android|ao|apartments|aq|aquarelle|ar|archi|army|arpa|as|asia|associates|at|attorney|au|auction|audio|auto|autos|aw|ax|axa|az|ba|band|bank|bar|barclaycard|barclays|bargains|bauhaus|bayern|bb|bbc|bbva|bd|be|beer|berlin|best|bf|bg|bh|bi|bible|bid|bike|bingo|bio|biz|bj|bl|black|blackfriday|bloomberg|blue|bm|bmw|bn|bnpparibas|bo|boats|bond|boo|boutique|bq|br|bridgestone|broker|brother|brussels|bs|bt|budapest|build|builders|business|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cbn|cc|cd|center|ceo|cern|cf|cfa|cfd|cg|ch|channel|chat|cheap|chloe|christmas|chrome|church|ci|cisco|citic|city|ck|cl|claims|cleaning|click|clinic|clothing|club|cm|cn|co|coach|codes|coffee|college|cologne|com|community|company|computer|condos|construction|consulting|contractors|cooking|cool|coop|corsica|country|coupons|courses|cr|credit|creditcard|cricket|crs|cruises|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|date|dating|datsun|day|dclk|de|deals|degree|delivery|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dj|dk|dm|dnp|do|docs|dog|doha|domains|doosan|download|durban|dvag|dz|earth|eat|ec|edu|education|ee|eg|eh|email|emerck|energy|engineer|engineering|enterprises|epson|equipment|er|erni|es|esq|estate|et|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|fail|faith|fan|fans|farm|fashion|feedback|fi|film|finance|financial|firmdale|fish|fishing|fit|fitness|fj|fk|flights|florist|flowers|flsmidth|fly|fm|fo|foo|football|forex|forsale|foundation|fr|frl|frogans|fund|furniture|futbol|fyi|ga|gal|gallery|garden|gb|gbiz|gd|gdn|ge|gent|gf|gg|ggee|gh|gi|gift|gifts|gives|gl|glass|gle|global|globo|gm|gmail|gmo|gmx|gn|gold|goldpoint|golf|goo|goog|google|gop|gov|gp|gq|gr|graphics|gratis|green|gripe|gs|gt|gu|guge|guide|guitars|guru|gw|gy|hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hk|hm|hn|hockey|holdings|holiday|homedepot|homes|honda|horse|host|hosting|house|how|hr|ht|hu|ibm|icbc|icu|id|ie|ifm|il|im|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insure|int|international|investments|io|iq|ir|irish|is|it|iwc|java|jcb|je|jetzt|jewelry|jll|jm|jo|jobs|joburg|jp|juegos|kaufen|kddi|ke|kg|kh|ki|kim|kitchen|kiwi|km|kn|koeln|komatsu|kp|kr|krd|kred|kw|ky|kyoto|kz|la|lacaixa|land|lat|latrobe|lawyer|lb|lc|lds|lease|leclerc|legal|lgbt|li|liaison|lidl|life|lighting|limited|limo|link|lk|loan|loans|lol|london|lotte|lotto|love|lr|ls|lt|ltda|lu|lupin|luxe|luxury|lv|ly|ma|madrid|maif|maison|management|mango|market|marketing|markets|marriott|mba|mc|md|me|media|meet|melbourne|meme|memorial|men|menu|mf|mg|mh|miami|mil|mini|mk|ml|mm|mma|mn|mo|mobi|moda|moe|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|mp|mq|mr|ms|mt|mtn|mtpc|mu|museum|mv|mw|mx|my|mz|na|nadex|nagoya|name|navy|nc|ne|nec|net|network|neustar|new|news|nexus|nf|ng|ngo|nhk|ni|nico|ninja|nissan|nl|no|np|nr|nra|nrw|ntt|nu|nyc|nz|okinawa|om|one|ong|onl|online|ooo|org|organic|osaka|otsuka|ovh|pa|page|panerai|paris|partners|parts|party|pe|pf|pg|ph|pharmacy|philips|photo|photography|photos|physio|piaget|pics|pictet|pictures|pink|pizza|pk|pl|place|plumbing|plus|pm|pn|pohl|poker|porn|post|pr|praxi|press|pro|prod|productions|prof|properties|property|ps|pt|pub|pw|py|qa|qpon|quebec|racing|re|realtor|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rich|rio|rip|ro|rocks|rodeo|rs|rsvp|ru|ruhr|run|rw|ryukyu|sa|saarland|sale|samsung|sandvik|sandvikcoromant|sap|sarl|saxo|sb|sc|sca|scb|schmidt|scholarships|school|schule|schwarz|science|scot|sd|se|seat|sener|services|sew|sex|sexy|sg|sh|shiksha|shoes|show|shriram|si|singles|site|sj|sk|ski|sky|sl|sm|sn|sncf|so|soccer|social|software|sohu|solar|solutions|sony|soy|space|spiegel|spreadbetting|sr|ss|st|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swiss|sx|sy|sydney|systems|sz|taipei|tatar|tattoo|tax|taxi|tc|td|team|tech|technology|tel|temasek|tennis|tf|tg|th|thd|theater|tickets|tienda|tips|tires|tirol|tj|tk|tl|tm|tn|to|today|tokyo|tools|top|toray|toshiba|tours|town|toys|tp|tr|trade|trading|training|travel|trust|tt|tui|tv|tw|tz|ua|ug|uk|um|university|uno|uol|us|uy|uz|va|vacations|vc|ve|vegas|ventures|versicherung|vet|vg|vi|viajes|video|villas|vision|vlaanderen|vn|vodka|vote|voting|voto|voyage|vu|wales|walter|wang|watch|webcam|website|wed|wedding|weir|wf|whoswho|wien|wiki|williamhill|win|wme|work|works|world|ws|wtc|wtf|xbox|xerox|xin|测试|परीक्षा|佛山|慈善|集团|在线|한국|ভারত|八卦|موقع|বাংলা|公益|公司|移动|我爱你|москва|испытание|қаз|онлайн|сайт|срб|бел|时尚|테스트|淡马锡|орг|삼성|சிங்கப்பூர்|商标|商店|商城|дети|мкд|טעסט|工行|中文网|中信|中国|中國|娱乐|谷歌|భారత్|ලංකා|測試|ભારત|भारत|آزمایشی|பரிட்சை|网店|संगठन|餐厅|网络|укр|香港|δοκιμή|飞利浦|إختبار|台湾|台灣|手机|мон|الجزائر|عمان|ایران|امارات|بازار|پاکستان|الاردن|بھارت|المغرب|السعودية|سودان|عراق|مليسيا|澳門|政府|شبكة|გე|机构|组织机构|健康|ไทย|سورية|рус|рф|تونس|みんな|グーグル|ελ|世界|ਭਾਰਤ|网址|游戏|vermögensberater|vermögensberatung|企业|信息|مصر|قطر|广东|இலங்கை|இந்தியா|հայ|新加坡|فلسطين|テスト|政务|xxx|xyz|yachts|yandex|ye|yodobashi|yoga|yokohama|youtube|yt|za|zip|zm|zone|zuerich|zw|oracle|xn--1qqw23a|xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--55qw42g|xn--55qx5d|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|xn--80ao21a|xn--80asehdb|xn--80aswg|xn--90a3ac|xn--90ais|xn--9et52u|xn--b4w605ferd|xn--c1avg|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--estv75g|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--gecrj9c|xn--h2brj9c|xn--hxt814e|xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1amh|xn--j6w193g|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a4f16a|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbayh7gpa|xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgberp4a5d4ar|xn--mgbpl2fh|xn--mgbx4cd0ab|xn--mxtq1m|xn--ngbc5azd|xn--node|xn--nqv7f|xn--nqv7fs00ema|xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--p1acf|xn--p1ai|xn--pgbs0dh|xn--q9jyb4c|xn--qcka1pmc|xn--rhqv96g|xn--s9brj9c|xn--ses554g|xn--unup4y|xn--vermgensberater-ctb|xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b)'; window.syntaxHighlightingRegexps = Object(); + var allDomains = '(abb|abbott|abogado|ac|academy|accenture|accountant|accountants|active|actor|ad|ads|adult|ae|aero|af|afl|ag|agency|ai|aig|airforce|al|allfinanz|alsace|am|amsterdam|an|android|ao|apartments|aq|aquarelle|ar|archi|army|arpa|as|asia|associates|at|attorney|au|auction|audio|auto|autos|aw|ax|axa|az|ba|band|bank|bar|barclaycard|barclays|bargains|bauhaus|bayern|bb|bbc|bbva|bd|be|beer|berlin|best|bf|bg|bh|bi|bible|bid|bike|bingo|bio|biz|bj|bl|black|blackfriday|bloomberg|blue|bm|bmw|bn|bnpparibas|bo|boats|bond|boo|boutique|bq|br|bridgestone|broker|brother|brussels|bs|bt|budapest|build|builders|business|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cbn|cc|cd|center|ceo|cern|cf|cfa|cfd|cg|ch|channel|chat|cheap|chloe|christmas|chrome|church|ci|cisco|citic|city|ck|cl|claims|cleaning|click|clinic|clothing|club|cm|cn|co|coach|codes|coffee|college|cologne|com|community|company|computer|condos|construction|consulting|contractors|cooking|cool|coop|corsica|country|coupons|courses|cr|credit|creditcard|cricket|crs|cruises|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|date|dating|datsun|day|dclk|de|deals|degree|delivery|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dj|dk|dm|dnp|do|docs|dog|doha|domains|doosan|download|durban|dvag|dz|earth|eat|ec|edu|education|ee|eg|eh|email|emerck|energy|engineer|engineering|enterprises|epson|equipment|er|erni|es|esq|estate|et|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|fail|faith|fan|fans|farm|fashion|feedback|fi|film|finance|financial|firmdale|fish|fishing|fit|fitness|fj|fk|flights|florist|flowers|flsmidth|fly|fm|fo|foo|football|forex|forsale|foundation|fr|frl|frogans|fund|furniture|futbol|fyi|ga|gal|gallery|garden|gb|gbiz|gd|gdn|ge|gent|gf|gg|ggee|gh|gi|gift|gifts|gives|gl|glass|gle|global|globo|gm|gmail|gmo|gmx|gn|gold|goldpoint|golf|goo|goog|google|gop|gov|gp|gq|gr|graphics|gratis|green|gripe|gs|gt|gu|guge|guide|guitars|guru|gw|gy|hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hk|hm|hn|hockey|holdings|holiday|homedepot|homes|honda|horse|host|hosting|house|how|hr|ht|hu|ibm|icbc|icu|id|ie|ifm|il|im|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insure|int|international|investments|io|iq|ir|irish|is|it|iwc|java|jcb|je|jetzt|jewelry|jll|jm|jo|jobs|joburg|jp|juegos|kaufen|kddi|ke|kg|kh|ki|kim|kitchen|kiwi|km|kn|koeln|komatsu|kp|kr|krd|kred|kw|ky|kyoto|kz|la|lacaixa|land|lat|latrobe|lawyer|lb|lc|lds|lease|leclerc|legal|lgbt|li|liaison|lidl|life|lighting|limited|limo|link|lk|loan|loans|lol|london|lotte|lotto|love|lr|ls|lt|ltda|lu|lupin|luxe|luxury|lv|ly|ma|madrid|maif|maison|management|mango|market|marketing|markets|marriott|mba|mc|md|me|media|meet|melbourne|meme|memorial|men|menu|mf|mg|mh|miami|mil|mini|mk|ml|mm|mma|mn|mo|mobi|moda|moe|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|mp|mq|mr|ms|mt|mtn|mtpc|mu|museum|mv|mw|mx|my|mz|na|nadex|nagoya|name|navy|nc|ne|nec|net|network|neustar|new|news|nexus|nf|ng|ngo|nhk|ni|nico|ninja|nissan|nl|no|np|nr|nra|nrw|ntt|nu|nyc|nz|okinawa|om|one|ong|onl|online|ooo|org|organic|osaka|otsuka|ovh|pa|page|panerai|paris|partners|parts|party|pe|pf|pg|ph|pharmacy|philips|photo|photography|photos|physio|piaget|pics|pictet|pictures|pink|pizza|pk|pl|place|plumbing|plus|pm|pn|pohl|poker|porn|post|pr|praxi|press|pro|prod|productions|prof|properties|property|ps|pt|pub|pw|py|qa|qpon|quebec|racing|re|realtor|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rich|rio|rip|ro|rocks|rodeo|rs|rsvp|ru|ruhr|run|rw|ryukyu|sa|saarland|sale|samsung|sandvik|sandvikcoromant|sap|sarl|saxo|sb|sc|sca|scb|schmidt|scholarships|school|schule|schwarz|science|scot|sd|se|seat|sener|services|sew|sex|sexy|sg|sh|shiksha|shoes|show|shriram|si|singles|site|sj|sk|ski|sky|sl|sm|sn|sncf|so|soccer|social|software|sohu|solar|solutions|sony|soy|space|spiegel|spreadbetting|sr|ss|st|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swiss|sx|sy|sydney|systems|sz|taipei|tatar|tattoo|tax|taxi|tc|td|team|tech|technology|tel|temasek|tennis|tf|tg|th|thd|theater|tickets|tienda|tips|tires|tirol|tj|tk|tl|tm|tn|to|today|tokyo|tools|top|toray|toshiba|tours|town|toys|tp|tr|trade|trading|training|travel|trust|tt|tui|tv|tw|tz|ua|ug|uk|um|university|uno|uol|us|uy|uz|va|vacations|vc|ve|vegas|ventures|versicherung|vet|vg|vi|viajes|video|villas|vision|vlaanderen|vn|vodka|vote|voting|voto|voyage|vu|wales|walter|wang|watch|webcam|website|wed|wedding|weir|wf|whoswho|wien|wiki|williamhill|win|wme|work|works|world|ws|wtc|wtf|xbox|xerox|xin|测试|परीक्षा|佛山|慈善|集团|在线|한국|ভারত|八卦|موقع|বাংলা|公益|公司|移动|我爱你|москва|испытание|қаз|онлайн|сайт|срб|бел|时尚|테스트|淡马锡|орг|삼성|சிங்கப்பூர்|商标|商店|商城|дети|мкд|טעסט|工行|中文网|中信|中国|中國|娱乐|谷歌|భారత్|ලංකා|測試|ભારત|भारत|آزمایشی|பரிட்சை|网店|संगठन|餐厅|网络|укр|香港|δοκιμή|飞利浦|إختبار|台湾|台灣|手机|мон|الجزائر|عمان|ایران|امارات|بازار|پاکستان|الاردن|بھارت|المغرب|السعودية|سودان|عراق|مليسيا|澳門|政府|شبكة|გე|机构|组织机构|健康|ไทย|سورية|рус|рф|تونس|みんな|グーグル|ελ|世界|ਭਾਰਤ|网址|游戏|vermögensberater|vermögensberatung|企业|信息|مصر|قطر|广东|இலங்கை|இந்தியா|հայ|新加坡|فلسطين|テスト|政务|xxx|xyz|yachts|yandex|ye|yodobashi|yoga|yokohama|youtube|yt|za|zip|zm|zone|zuerich|zw|oracle|xn--1qqw23a|xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--55qw42g|xn--55qx5d|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|xn--80ao21a|xn--80asehdb|xn--80aswg|xn--90a3ac|xn--90ais|xn--9et52u|xn--b4w605ferd|xn--c1avg|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--estv75g|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--gecrj9c|xn--h2brj9c|xn--hxt814e|xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1amh|xn--j6w193g|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a4f16a|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbayh7gpa|xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgberp4a5d4ar|xn--mgbpl2fh|xn--mgbx4cd0ab|xn--mxtq1m|xn--ngbc5azd|xn--node|xn--nqv7f|xn--nqv7fs00ema|xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--p1acf|xn--p1ai|xn--pgbs0dh|xn--q9jyb4c|xn--qcka1pmc|xn--rhqv96g|xn--s9brj9c|xn--ses554g|xn--unup4y|xn--vermgensberater-ctb|xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b)'; window.syntaxHighlightingRegexps.externalMention = XRegExp.cache('(^|\\s|\\.|
| )(@)[a-zA-Z0-9]+(@)[\\p{L}\\p{N}\\-\\.]+(\\.)(' + allDomains + ')($|\\s|\\.|\\,|\\:|\\-|\\<|\\!|\\?|\\&)'); window.syntaxHighlightingRegexps.mention = /(^|\s|\.|
| )(@)[a-zA-Z0-9]+($|\s|\.|\,|\:|\-|\<|\!|\?|\&)/; window.syntaxHighlightingRegexps.tag = XRegExp.cache('(^|\\s|\\.|
| )(\\#)[\\p{L}\\p{N}\\-\\.]+($|\\s|\\.|\\,|\\:|\\-|\\<|\\!|\\?|\\&)'); - window.syntaxHighlightingRegexps.group = /(^|\s|\.|
| )(\!)[a-zA-Z0-9]+($|\s|\.|\,|\:|\-|\<|\!|\?|\&)/; window.syntaxHighlightingRegexps.url = XRegExp.cache('(^|\\s|\\.|
| )(http\\:\\/\\/|https\:\\/\\/)([\\p{L}\\p{N}\\-\\.]+)?(\\.)(' + allDomains + ')(\\/[\\p{L}\\p{N}\\%\\!\\*\\\'\\(\\)\\;\\:\\@\\&\\=\\+\\$\\,\\/\\?\\#\\[\\]\\-\\_\\.\\~]+)?(\\/)?($|\\s|\\,|\\:|\\-|\\<|\\!|\\?|\\&)'); window.syntaxHighlightingRegexps.urlWithoutProtocol = XRegExp.cache('(^|\\s|\\.|
| )[\\p{L}\\p{N}\\-\\.]+(\\.)(' + allDomains + ')(\\/[\\p{L}\\p{N}\\%\\!\\*\\\'\\(\\)\\;\\:\\@\\&\\=\\+\\$\\,\\/\\?\\#\\[\\]\\-\\_\\.\\~]+)?(\\/)?($|\\s|\\.|\\,|\\:|\\-|\\<|\\!|\\?|\\&)'); window.syntaxHighlightingRegexps.email = XRegExp.cache('(^|\\s|\\.|
| )([a-zA-Z0-9\\!\\#\\$\\%\\&\\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~\\.]+)?(@)[\\p{L}\\p{N}\\-\\.]+(\\.)(' + allDomains + ')($|\\s|\\.|\\,|\\:|\\-|\\<|\\!|\\?|\\&)'); + cacheSyntaxHighlightingGroups(); + } + +/* · + · + · Cache syntax highlighting for groups + · + · · · · · · · · · */ + +function cacheSyntaxHighlightingGroups() { + if(window.groupNicknamesAndLocalAliases.length > 0) { + var allGroupNicknamesAndLocalAliases = '(' + window.groupNicknamesAndLocalAliases.join('|') + ')'; + window.syntaxHighlightingRegexps.group = XRegExp.cache('(^|\\s|\\.|
| )(\\!)' + allGroupNicknamesAndLocalAliases + '($|\\s|\\.|\\,|\\:|\\-|\\<|\\!|\\?|\\&)'); + } } @@ -923,8 +935,10 @@ function timestampToTwitterDate(timestamp) { return day+' '+month+' '+date+' '+hour+':'+min+':'+sec+' +0000 '+year; } function parseDate(str) { - var v=str.split(' '); - return new Date(Date.parse(v[1]+" "+v[2]+", "+v[5]+" "+v[3]+" "+v[4])); + if(typeof str != 'undefined') { + var v=str.split(' '); + return new Date(Date.parse(v[1]+" "+v[2]+", "+v[5]+" "+v[3]+" "+v[4])); + } } diff --git a/js/qvitter.js b/js/qvitter.js index b64757f..c89f5de 100644 --- a/js/qvitter.js +++ b/js/qvitter.js @@ -533,10 +533,14 @@ function doLogin(streamToSet) { // get all users i'm following for autosuggestion window.following = new Array(); + window.groupMemberships = new Array(); + window.groupNicknamesAndLocalAliases = new Array(); + getFromAPI('qvitter/allfollowing/' + window.loggedIn.screen_name + '.json',function(data){ - if(data) { + + if(data.users) { var i=0; - $.each(data,function(k,v){ + $.each(data.users,function(k,v){ if(v[2] === false) { var avatar = window.defaultAvatarStreamSize; } else { var avatar = v[2]; } if(v[3]) { @@ -547,20 +551,39 @@ function doLogin(streamToSet) { window.following[i] = { 'id': k,'name': v[0], 'username': v[1],'avatar': avatar, 'url':v[3] }; i++; }); + } - cacheSyntaxHighlighting(); // do this now not to stall slow computers + if(data.groups) { + var i=0; + $.each(data.groups,function(k,v){ + if(v[2] === false || v[2] === null) { var avatar = window.defaultAvatarStreamSize; } + else { var avatar = v[2]; } + if(v[3]) { + // extract server base url + v[3] = v[3].substring(v[3].indexOf('://')+3); + v[3] = v[3].substring(0, v[3].indexOf('/')); + } + v[0] = v[0] || v[1]; // if name is null we go with username there too + window.groupMemberships[i] = { 'id': k,'name': v[0], 'username': v[1],'avatar': avatar, 'url':v[3] }; + window.groupNicknamesAndLocalAliases[i] = v[1]; + i++; + }); + } - // we might have cached text for the queet box - // (we need to get the mentions suggestions and cache the syntax highlighting before doing this) - var cachedQueetBoxData = localStorageObjectCache_GET('queetBoxInput','queet-box'); - var cachedQueetBoxDataText = $('
').html(cachedQueetBoxData).text(); - if(cachedQueetBoxData) { - queetBox = $('#queet-box'); - queetBox.click(); - queetBox.html(cachedQueetBoxData); - setSelectionRange(queetBox[0], cachedQueetBoxDataText.length, cachedQueetBoxDataText.length); - queetBox.trigger('input'); - } + // do this now not to stall slow computers, also we know of group memberships to highlight now + cacheSyntaxHighlighting(); + cacheSyntaxHighlightingGroups(); + + // we might have cached text for the queet box + // (we need to get the mentions suggestions and cache the syntax highlighting before doing this) + var cachedQueetBoxData = localStorageObjectCache_GET('queetBoxInput','queet-box'); + var cachedQueetBoxDataText = $('
').html(cachedQueetBoxData).text(); + if(cachedQueetBoxData) { + queetBox = $('#queet-box'); + queetBox.click(); + queetBox.html(cachedQueetBoxData); + setSelectionRange(queetBox[0], cachedQueetBoxDataText.length, cachedQueetBoxDataText.length); + queetBox.trigger('input'); } }); @@ -1195,9 +1218,9 @@ $('body').on('click','a', function(e) { data.nickname = data.nickname || ''; data.fullname = data.fullname || ''; - data.stream_logo = data.stream_logo || 'http://quitter.se/theme/quitter-theme2/default-avatar-stream.png'; - data.homepage_logo = data.homepage_logo || 'http://quitter.se/theme/quitter-theme2/default-avatar-profile.png'; - data.original_logo = data.original_logo || 'http://quitter.se/theme/quitter-theme2/default-avatar-profile.png'; + data.stream_logo = data.stream_logo || window.defaultAvatarStreamSize; + data.homepage_logo = data.homepage_logo || window.defaultAvatarProfileSize; + data.original_logo = data.original_logo || window.defaultAvatarProfileSize; data.description = data.description || ''; data.homepage = data.homepage || ''; data.url = data.url || ''; @@ -2104,6 +2127,19 @@ $('body').on('click', '.queet-toolbar button',function () { popUpAction('popup-sending', '',queetHtml.replace('class="stream-item conversation','class="stream-item'),false); } + // maybe post queet in groups + var postToGroups = ''; + var postToGropsArray = new Array(); + $.each(queetBox.siblings('.post-to-group'),function(){ + postToGropsArray.push($(this).data('group-id')); + }); + if(postToGropsArray.length > 0) { + postToGroups = postToGropsArray.join(':'); + } + + // remove any post-to-group-divs + queetBox.siblings('.post-to-group').remove(); + // remove any replying-to classes $('.stream-item').removeClass('replying-to'); @@ -2114,7 +2150,7 @@ $('body').on('click', '.queet-toolbar button',function () { setTimeout('checkForNewQueets()', 1000); // post queet - postQueetToAPI(queetText, in_reply_to_status_id, function(data){ if(data) { + postQueetToAPI(queetText, in_reply_to_status_id, postToGroups, function(data){ if(data) { // show real queet var new_queet = Array(); @@ -2229,6 +2265,11 @@ $('body').on('mousedown','.syntax-two',function () { }); $('body').on('blur','.queet-box-syntax',function (e) { + // empty the mention suggestions on blur, timeout because we want to capture clicks in .mentions-suggestions + setTimeout(function(){ + $(this).siblings('.mentions-suggestions').empty(); + },10); + // don't collapse if a toolbar button has been clicked var clickedToolbarButtons = $(this).siblings('.queet-toolbar').find('button.clicked'); if(clickedToolbarButtons.length>0) { @@ -2408,13 +2449,31 @@ $('body').on('keydown', '.queet-box-syntax', function(e) { }); function useSelectedMention(queetBox){ + // use selected if(queetBox.siblings('.mentions-suggestions').children('div.selected').length > 0) { - var username = queetBox.siblings('.mentions-suggestions').children('div.selected').children('span').html(); + var selectedSuggestion = queetBox.siblings('.mentions-suggestions').children('div.selected'); } // if none selected, take top suggestion else { - var username = queetBox.siblings('.mentions-suggestions').children('div').first().children('span').html(); + var selectedSuggestion = queetBox.siblings('.mentions-suggestions').children('div').first(); + } + + var username = selectedSuggestion.children('span').html(); + var name = selectedSuggestion.children('strong').html(); + + // if this is a group, we remember its id, the user might be member of multiple groups with the same username + if(selectedSuggestion.hasClass('group-suggestion')) { + var groupId = selectedSuggestion.data('group-id'); + if(queetBox.siblings('.post-to-group[data-group-id="' + groupId + '"]').length < 1) { + if(queetBox.siblings('.post-to-group').length>0) { + var addAfter = queetBox.siblings('.post-to-group').last(); + } + else { + var addAfter = queetBox; + } + addAfter.after('
' + name + '
'); + } } // replace the halfwritten username with the one we want @@ -2428,7 +2487,18 @@ function useSelectedMention(queetBox){ queetBox.trigger('input'); // avoid some flickering } -// check for mentions +// check for removed group mentions +$('body').on('keyup', 'div.queet-box-syntax', function(e) { + var groupMentions = $(this).siblings('.post-to-group'); + var queetBoxContent = $(this).text(); + $.each(groupMentions,function(){ + if(queetBoxContent.indexOf('!' + $(this).data('group-username')) == -1) { + $(this).remove(); + } + }); + }); + +// check for user mentions window.lastMention = new Object(); $('body').on('keyup', 'div.queet-box-syntax', function(e) { @@ -2455,7 +2525,7 @@ $('body').on('keyup', 'div.queet-box-syntax', function(e) { } if((contents.lastIndexOf('@')+match[0].length) == cursorPos) { - queetBox.siblings('.mentions-suggestions').empty(); + queetBox.siblings('.mentions-suggestions').children('.user-suggestion').remove(); queetBox.siblings('.mentions-suggestions').css('top',(queetBox.height()+20) + 'px'); var term = match[0].substring(match[0].lastIndexOf('@')+1, match[0].length).toLowerCase(); window.lastMention.mentionPos = mentionPos; @@ -2487,17 +2557,90 @@ $('body').on('keyup', 'div.queet-box-syntax', function(e) { if(suggestionsUsernameCount[this.username]>1 && this.url !== false) { serverHtml = '@' + this.url; } - queetBox.siblings('.mentions-suggestions').append('
' + this.name + ' @' + this.username + serverHtml + '
') + queetBox.siblings('.mentions-suggestions').append('
' + this.name + ' @' + this.username + serverHtml + '
') }); } else { - queetBox.siblings('.mentions-suggestions').empty(); + queetBox.siblings('.mentions-suggestions').children('.user-suggestion').remove(); } } else { - queetBox.siblings('.mentions-suggestions').empty(); + queetBox.siblings('.mentions-suggestions').children('.user-suggestion').remove(); + } + } + }); + + +// check for group mentions +$('body').on('keyup', 'div.queet-box-syntax', function(e) { + + var queetBox = $(this); + var cursorPosArray = getSelectionInElement(queetBox[0]); + var cursorPos = cursorPosArray[0]; + + // add space before linebreaks (to separate mentions in beginning of new lines when .text():ing later) + if(e.keyCode == '13') { + e.preventDefault(); + var range = createRangeFromCharacterIndices(queetBox[0], cursorPos, cursorPos); + range.insertNode(document.createTextNode(" \n")); + } + else if(e.keyCode != '40' && e.keyCode != '38' && e.keyCode != '13' && e.keyCode != '9') { + var contents = queetBox.text().substring(0,cursorPos); + var mentionPos = contents.lastIndexOf('!'); + var check_contents = contents.substring(mentionPos - 1, cursorPos); + var regex = /(^|\s|\.|\n)(!)[a-zA-Z0-9]+/; + var match = check_contents.match(regex); + if (contents.indexOf('!') >= 0 && match) { + + if(contents.lastIndexOf('!') > 1) { + match[0] = match[0].substring(1,match[0].length); + } + if((contents.lastIndexOf('!')+match[0].length) == cursorPos) { + + queetBox.siblings('.mentions-suggestions').children('.group-suggestion').remove(); + queetBox.siblings('.mentions-suggestions').css('top',(queetBox.height()+20) + 'px'); + var term = match[0].substring(match[0].lastIndexOf('!')+1, match[0].length).toLowerCase(); + window.lastMention.mentionPos = mentionPos; + window.lastMention.cursorPos = cursorPos; + + + // see if any group we're member of matches + var suggestionsToShow = []; + var suggestionsUsernameCount = {}; + $.each(window.groupMemberships,function(){ + var userregex = new RegExp(term); + if(this.username.toLowerCase().match(userregex) || this.name.toLowerCase().match(userregex)) { + suggestionsToShow.push({id:this.id, avatar:this.avatar, name:this.name, username:this.username,url:this.url}); + + // count the usernames to see if we need to show the server for any of them + if(typeof suggestionsUsernameCount[this.username] != 'undefined') { + suggestionsUsernameCount[this.username] = suggestionsUsernameCount[this.username] + 1; + } + else { + suggestionsUsernameCount[this.username] = 1; + } + } + }); + + // show matches + $.each(suggestionsToShow,function(){ + var serverHtml = ''; + if(suggestionsUsernameCount[this.username]>1 && this.url !== false) { + serverHtml = this.url + '/group/'; + } + queetBox.siblings('.mentions-suggestions').append('
' + this.name + ' !' + this.username + '
') + }); + + } + else { + queetBox.siblings('.mentions-suggestions').children('.group-suggestion').remove(); + } + + } + else { + queetBox.siblings('.mentions-suggestions').children('.group-suggestion').remove(); } } });