site notice, notifications, etc
This commit is contained in:
parent
146231dbe1
commit
cc3eb5fdda
|
@ -74,6 +74,16 @@ class QvitterPlugin extends Plugin {
|
||||||
return $settings[$setting];
|
return $settings[$setting];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// make sure we have a notifications table
|
||||||
|
function onCheckSchema()
|
||||||
|
{
|
||||||
|
$schema = Schema::get();
|
||||||
|
$schema->ensureTable('qvitternotification', QvitterNotification::schemaDef());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// route/reroute urls
|
||||||
public function onRouterInitialized($m)
|
public function onRouterInitialized($m)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -102,8 +112,18 @@ class QvitterPlugin extends Plugin {
|
||||||
'id' => Nickname::INPUT_FMT));
|
'id' => Nickname::INPUT_FMT));
|
||||||
$m->connect('api/qvitter/statuses/mentions.:format',
|
$m->connect('api/qvitter/statuses/mentions.:format',
|
||||||
array('action' => 'apiqvittermentions'));
|
array('action' => 'apiqvittermentions'));
|
||||||
|
$m->connect('api/qvitter/statuses/notifications.json',
|
||||||
|
array('action' => 'apiqvitternotifications'));
|
||||||
|
$m->connect(':nickname/notifications',
|
||||||
|
array('action' => 'qvitter',
|
||||||
|
'nickname' => Nickname::INPUT_FMT));
|
||||||
|
$m->connect('api/qvitter/newnotifications.json',
|
||||||
|
array('action' => 'ApiNewNotifications'));
|
||||||
$m->connect('settings/qvitter',
|
$m->connect('settings/qvitter',
|
||||||
array('action' => 'qvittersettings'));
|
array('action' => 'qvittersettings'));
|
||||||
|
$m->connect('panel/qvitter',
|
||||||
|
array('action' => 'qvitteradminsettings'));
|
||||||
|
common_config_append('admin', 'panels', 'qvitteradm');
|
||||||
$m->connect('main/qlogin',
|
$m->connect('main/qlogin',
|
||||||
array('action' => 'qvitterlogin'));
|
array('action' => 'qvitterlogin'));
|
||||||
|
|
||||||
|
@ -181,7 +201,11 @@ class QvitterPlugin extends Plugin {
|
||||||
URLMapperOverwrite::overwrite_variable($m, 'tag/:tag',
|
URLMapperOverwrite::overwrite_variable($m, 'tag/:tag',
|
||||||
array('action' => 'showstream'),
|
array('action' => 'showstream'),
|
||||||
array('tag' => Router::REGEX_TAG),
|
array('tag' => Router::REGEX_TAG),
|
||||||
'qvitter');
|
'qvitter');
|
||||||
|
URLMapperOverwrite::overwrite_variable($m, 'notice/:notice',
|
||||||
|
array('action' => 'shownotice'),
|
||||||
|
array('notice' => '[0-9]+'),
|
||||||
|
'qvitter');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -207,6 +231,31 @@ class QvitterPlugin extends Plugin {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu item for admin panel
|
||||||
|
*
|
||||||
|
* @param Action $action action being executed
|
||||||
|
*
|
||||||
|
* @return boolean hook return
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onEndAdminPanelNav($action)
|
||||||
|
{
|
||||||
|
|
||||||
|
$action_name = $action->trimmed('action');
|
||||||
|
|
||||||
|
$action->out->menuItem(common_local_url('qvitteradminsettings'),
|
||||||
|
// TRANS: Poll plugin menu item on user settings page.
|
||||||
|
_m('MENU', 'Qvitter'),
|
||||||
|
// TRANS: Poll plugin tooltip for user settings menu item.
|
||||||
|
_m('Qvitter Sidebar Notice'),
|
||||||
|
$action_name === 'qvitteradminsettings');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,6 +298,163 @@ class QvitterPlugin extends Plugin {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert into notification table
|
||||||
|
*/
|
||||||
|
function insertNotification($to_profile_id, $from_profile_id, $ntype, $notice_id=false)
|
||||||
|
{
|
||||||
|
|
||||||
|
// never notify myself
|
||||||
|
if($to_profile_id != $from_profile_id) {
|
||||||
|
|
||||||
|
// insert
|
||||||
|
$notif = new QvitterNotification();
|
||||||
|
$notif->to_profile_id = $to_profile_id;
|
||||||
|
$notif->from_profile_id = $from_profile_id;
|
||||||
|
$notif->ntype = $ntype;
|
||||||
|
$notif->notice_id = $notice_id;
|
||||||
|
$notif->created = common_sql_now();
|
||||||
|
if (!$notif->insert()) {
|
||||||
|
common_log_db_error($notif, 'INSERT', __FILE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert likes in notification table
|
||||||
|
*/
|
||||||
|
public function onEndFavorNotice($profile, $notice)
|
||||||
|
{
|
||||||
|
|
||||||
|
// don't notify people favoriting their own notices
|
||||||
|
if($notice->profile_id != $profile->id) {
|
||||||
|
$this->insertNotification($notice->profile_id, $profile->id, 'like', $notice->id, $notice->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove likes in notification table on dislike
|
||||||
|
*/
|
||||||
|
public function onEndDisfavorNotice($profile, $notice)
|
||||||
|
{
|
||||||
|
$notif = new QvitterNotification();
|
||||||
|
$notif->from_profile_id = $profile->id;
|
||||||
|
$notif->notice_id = $notice->id;
|
||||||
|
$notif->ntype = 'like';
|
||||||
|
$notif->delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert notifications for replies, mentions and repeats
|
||||||
|
*
|
||||||
|
* @return boolean hook flag
|
||||||
|
*/
|
||||||
|
function onStartNoticeDistribute($notice) {
|
||||||
|
|
||||||
|
|
||||||
|
// repeats
|
||||||
|
if ($notice->isRepeat()) {
|
||||||
|
$repeated_notice = Notice::getKV('id', $notice->repeat_of);
|
||||||
|
if ($repeated_notice instanceof Notice) {
|
||||||
|
$this->insertNotification($repeated_notice->profile_id, $notice->profile_id, 'repeat', $repeated_notice->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// replies and mentions (no notifications for these if this is a repeat)
|
||||||
|
else {
|
||||||
|
// check for reply to insert in notifications
|
||||||
|
if($notice->reply_to) {
|
||||||
|
$replyparent = $notice->getParent();
|
||||||
|
$replyauthor = $replyparent->getProfile();
|
||||||
|
if ($replyauthor instanceof Profile) {
|
||||||
|
$reply_notification_to = $replyauthor->id;
|
||||||
|
$this->insertNotification($replyauthor->id, $notice->profile_id, 'reply', $notice->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for mentions to insert in notifications
|
||||||
|
$mentions = common_find_mentions($notice->content, $notice);
|
||||||
|
$sender = Profile::getKV($notice->profile_id);
|
||||||
|
foreach ($mentions as $mention) {
|
||||||
|
foreach ($mention['mentioned'] as $mentioned) {
|
||||||
|
|
||||||
|
// Not from blocked profile
|
||||||
|
$mentioned_user = User::getKV('id', $mentioned->id);
|
||||||
|
if ($mentioned_user instanceof User && $mentioned_user->hasBlocked($sender)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only notify if mentioned user is not already notified for reply
|
||||||
|
if($reply_notification_to != $mentioned->id) {
|
||||||
|
$this->insertNotification($mentioned->id, $notice->profile_id, 'mention', $notice->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete any notifications tied to deleted notices and un-repeats
|
||||||
|
*
|
||||||
|
* @return boolean hook flag
|
||||||
|
*/
|
||||||
|
public function onNoticeDeleteRelated($notice)
|
||||||
|
{
|
||||||
|
|
||||||
|
$notif = new QvitterNotification();
|
||||||
|
|
||||||
|
// unrepeats
|
||||||
|
if ($notice->isRepeat()) {
|
||||||
|
$repeated_notice = Notice::getKV('id', $notice->repeat_of);
|
||||||
|
$notif->notice_id = $repeated_notice->id;
|
||||||
|
$notif->from_profile_id = $notice->profile_id;
|
||||||
|
}
|
||||||
|
// notices
|
||||||
|
else {
|
||||||
|
$notif->notice_id = $notice->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notif->delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add notification on subscription, remove on unsubscribe
|
||||||
|
*
|
||||||
|
* @return boolean hook flag
|
||||||
|
*/
|
||||||
|
public function onEndSubscribe($subscriber, $other)
|
||||||
|
{
|
||||||
|
if(Subscription::exists($subscriber, $other)) {
|
||||||
|
$this->insertNotification($other->id, $subscriber->id, 'follow');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public function onEndUnsubscribe($subscriber, $other)
|
||||||
|
{
|
||||||
|
if(!Subscription::exists($subscriber, $other)) {
|
||||||
|
$notif = new QvitterNotification();
|
||||||
|
$notif->to_profile_id = $other->id;
|
||||||
|
$notif->from_profile_id = $subscriber->id;
|
||||||
|
$notif->ntype = 'follow';
|
||||||
|
$notif->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
24
README.md
24
README.md
|
@ -45,14 +45,24 @@ TODO
|
||||||
|
|
||||||
1. "following you" badge on other peoples profiles
|
1. "following you" badge on other peoples profiles
|
||||||
|
|
||||||
|
1. better user popup, with e.g. latest queets
|
||||||
|
|
||||||
|
1. Faq
|
||||||
|
|
||||||
|
1. DM's
|
||||||
|
|
||||||
|
1. lists
|
||||||
|
|
||||||
|
1. user actions-cog wheel in users lists, with block, list etc
|
||||||
|
|
||||||
|
1. proxy to non-https for getting conversations the instance doesn't have via jsonp
|
||||||
|
|
||||||
|
1. preview different types of attachments, not just images. e.g. mp3's, torrents etc etc
|
||||||
|
|
||||||
1. Join _new_ external groups and follow _new_ external users ("New" meaning users/groups that the server don't know yet)
|
1. Join _new_ external groups and follow _new_ external users ("New" meaning users/groups that the server don't know yet)
|
||||||
|
|
||||||
2. Creating groups, make admin, block user
|
2. Creating groups, make admin, block user
|
||||||
|
|
||||||
3. Background image uploading/editing
|
|
||||||
|
|
||||||
6. Auto url-shortening setting under queet box
|
|
||||||
|
|
||||||
7. Settings (e.g. don't show replies to people I don't follow)
|
7. Settings (e.g. don't show replies to people I don't follow)
|
||||||
|
|
||||||
9. Image/file upload
|
9. Image/file upload
|
||||||
|
@ -65,14 +75,8 @@ TODO
|
||||||
|
|
||||||
14. More languages, maybe make proper po/mo-files
|
14. More languages, maybe make proper po/mo-files
|
||||||
|
|
||||||
15. Notice-page
|
|
||||||
|
|
||||||
16. Admin-interface
|
16. Admin-interface
|
||||||
|
|
||||||
16. New api for serving _number_ of new items in several streams (to show number of new items in menu/history)
|
|
||||||
|
|
||||||
17. Notifications-page with likes and repeats
|
|
||||||
|
|
||||||
17. New "expand queet" api for getting conversation, retweets, favs and attachment in the same request
|
17. New "expand queet" api for getting conversation, retweets, favs and attachment in the same request
|
||||||
|
|
||||||
19. Node.js long polling server and an new api that serve aggregate of all polling users requests in one go
|
19. Node.js long polling server and an new api that serve aggregate of all polling users requests in one go
|
99
actions/apinewnotifications.php
Normal file
99
actions/apinewnotifications.php
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Qvitter: Unread notifications
|
||||||
|
*
|
||||||
|
* PHP version 5
|
||||||
|
*
|
||||||
|
* LICENCE: This program 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @category API
|
||||||
|
* @package GNUsocial
|
||||||
|
* @author Hannes Mannerheim <h@nnesmannerhe.im>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://www.gnu.org/software/social/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
|
class ApiNewNotificationsAction extends ApiAction
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*/
|
||||||
|
protected function prepare(array $args=array())
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function handle()
|
||||||
|
{
|
||||||
|
parent::handle();
|
||||||
|
|
||||||
|
$user_id = Profile::current()->id;
|
||||||
|
$new_notifications = array();
|
||||||
|
if($user_id) {
|
||||||
|
$notification = new QvitterNotification();
|
||||||
|
|
||||||
|
$notification->selectAdd();
|
||||||
|
$notification->selectAdd('ntype');
|
||||||
|
$notification->selectAdd('count(id) as count');
|
||||||
|
$notification->whereAdd("(to_profile_id = '".$user_id."')");
|
||||||
|
$notification->groupBy('ntype');
|
||||||
|
$notification->whereAdd("(is_seen = '0')");
|
||||||
|
$notification->find();
|
||||||
|
|
||||||
|
while ($notification->fetch()) {
|
||||||
|
$new_notifications[$notification->ntype] = $notification->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$new_notifications = 'You must be logged in.';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($new_notifications);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if read only.
|
||||||
|
*
|
||||||
|
* MAY override
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean is read only action?
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
198
actions/apiqvitternotifications.php
Normal file
198
actions/apiqvitternotifications.php
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
<?php
|
||||||
|
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· Q V I T T E R ·
|
||||||
|
· ·
|
||||||
|
· http://github.com/hannesmannerheim/qvitter ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· <o) ·
|
||||||
|
· /_//// ·
|
||||||
|
· (____/ ·
|
||||||
|
· (o< ·
|
||||||
|
· o> \\\\_\ ·
|
||||||
|
· \\) \____) ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· 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 ·
|
||||||
|
· your option) any later version. ·
|
||||||
|
· ·
|
||||||
|
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||||
|
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
|
||||||
|
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
|
||||||
|
· more details. ·
|
||||||
|
· ·
|
||||||
|
· You should have received a copy of the GNU Affero General Public License ·
|
||||||
|
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||||
|
· ·
|
||||||
|
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||||
|
· ·
|
||||||
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||||
|
|
||||||
|
if (!defined('STATUSNET')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiQvitterNotificationsAction extends ApiPrivateAuthAction
|
||||||
|
{
|
||||||
|
var $notifications = null;
|
||||||
|
var $notices = null;
|
||||||
|
var $profiles = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take arguments for running
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST args
|
||||||
|
*
|
||||||
|
* @return boolean success flag
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function prepare($args)
|
||||||
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
|
$this->notifications = $this->getNotifications();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the request
|
||||||
|
*
|
||||||
|
* Just show the notices
|
||||||
|
*
|
||||||
|
* @param array $args $_REQUEST data (unused)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
parent::handle($args);
|
||||||
|
$this->showTimeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the timeline of notices
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function showTimeline()
|
||||||
|
{
|
||||||
|
|
||||||
|
$notice = null;
|
||||||
|
|
||||||
|
$notifications_populated = array();
|
||||||
|
|
||||||
|
foreach($this->notifications as $notification) {
|
||||||
|
|
||||||
|
// all but follow has an notice
|
||||||
|
if($notification->ntype != 'follow') {
|
||||||
|
$notice = self::twitterSimpleStatusArray(Notice::getKV($notification->notice_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
$notifications_populated[] = array(
|
||||||
|
'id'=> $notification->id,
|
||||||
|
'from_profile'=> self::twitterUserArray(Profile::getKV($notification->from_profile_id)),
|
||||||
|
'ntype'=> $notification->ntype,
|
||||||
|
'notice'=> $notice,
|
||||||
|
'created_at'=>self::dateTwitter($notification->created),
|
||||||
|
'is_seen'=>$notification->is_seen
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark as seen
|
||||||
|
foreach($this->notifications as $notification) {
|
||||||
|
if($notification->is_seen == 0) {
|
||||||
|
$notification->is_seen = 1;
|
||||||
|
$notification->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->initDocument('json');
|
||||||
|
$this->showJsonObjects($notifications_populated);
|
||||||
|
$this->endDocument('json');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get notices
|
||||||
|
*
|
||||||
|
* @return array notices
|
||||||
|
*/
|
||||||
|
function getNotifications()
|
||||||
|
{
|
||||||
|
$notices = array();
|
||||||
|
|
||||||
|
$profile = ($this->auth_user) ? $this->auth_user->getProfile() : null;
|
||||||
|
|
||||||
|
$stream = new NotificationStream($profile);
|
||||||
|
|
||||||
|
$notifications = $stream->getNotifications(($this->page - 1) * $this->count,
|
||||||
|
$this->count,
|
||||||
|
$this->since_id,
|
||||||
|
$this->max_id);
|
||||||
|
|
||||||
|
$notifications = $notifications->fetchAll();
|
||||||
|
|
||||||
|
return $notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this action read only?
|
||||||
|
*
|
||||||
|
* @param array $args other arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
function isReadOnly($args)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When was this feed last modified?
|
||||||
|
*
|
||||||
|
* @return string datestamp of the latest notice in the stream
|
||||||
|
*/
|
||||||
|
function lastModified()
|
||||||
|
{
|
||||||
|
if (!empty($this->notifications) && (count($this->notifications) > 0)) {
|
||||||
|
return strtotime($this->notifications[0]->created);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity tag for this stream
|
||||||
|
*
|
||||||
|
* Returns an Etag based on the action name, language, and
|
||||||
|
* timestamps of the first and last notice in the timeline
|
||||||
|
*
|
||||||
|
* @return string etag
|
||||||
|
*/
|
||||||
|
function etag()
|
||||||
|
{
|
||||||
|
if (!empty($this->notifications) && (count($this->notifications) > 0)) {
|
||||||
|
|
||||||
|
$last = count($this->notifications) - 1;
|
||||||
|
|
||||||
|
return '"' . implode(
|
||||||
|
':',
|
||||||
|
array($this->arg('action'),
|
||||||
|
common_user_cache_hash($this->auth_user),
|
||||||
|
common_language(),
|
||||||
|
strtotime($this->notifications[0]->created),
|
||||||
|
strtotime($this->notifications[$last]->created))
|
||||||
|
)
|
||||||
|
. '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,38 +1,37 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
· ·
|
||||||
*
|
· ·
|
||||||
* Show the public timeline
|
· Q V I T T E R ·
|
||||||
*
|
· ·
|
||||||
* PHP version 5
|
· http://github.com/hannesmannerheim/qvitter ·
|
||||||
*
|
· ·
|
||||||
* LICENCE: This program is free software: you can redistribute it and/or modify
|
· ·
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
· <o) ·
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
· /_//// ·
|
||||||
* (at your option) any later version.
|
· (____/ ·
|
||||||
*
|
· (o< ·
|
||||||
* This program is distributed in the hope that it will be useful,
|
· o> \\\\_\ ·
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
· \\) \____) ·
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
· ·
|
||||||
* GNU Affero General Public License for more details.
|
· ·
|
||||||
*
|
· ·
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
· Qvitter is free software: you can redistribute it and / or modify it ·
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
· 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 ·
|
||||||
* @category API
|
· your option) any later version. ·
|
||||||
* @package StatusNet
|
· ·
|
||||||
* @author Craig Andrews <candrews@integralblue.com>
|
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||||
* @author Evan Prodromou <evan@status.net>
|
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
|
||||||
* @author Jeffery To <jeffery.to@gmail.com>
|
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
|
||||||
* @author mac65 <mac65@mac65.com>
|
· more details. ·
|
||||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
· ·
|
||||||
* @author Robin Millette <robin@millette.info>
|
· You should have received a copy of the GNU Affero General Public License ·
|
||||||
* @author Zach Copley <zach@status.net>
|
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||||
* @copyright 2009 StatusNet, Inc.
|
· ·
|
||||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
· ·
|
||||||
* @link http://status.net/
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||||
*/
|
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
if (!defined('STATUSNET')) {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -54,94 +53,6 @@ if (!defined('STATUSNET')) {
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* External API usage documentation. Please update when you change how this method works. */
|
|
||||||
|
|
||||||
/*! @page publictimeline statuses/public_timeline
|
|
||||||
|
|
||||||
@section Description
|
|
||||||
Returns the 20 most recent notices from users throughout the system who have
|
|
||||||
uploaded their own avatars. Depending on configuration, it may or may not
|
|
||||||
not include notices from automatic posting services.
|
|
||||||
|
|
||||||
@par URL patterns
|
|
||||||
@li /api/statuses/public_timeline.:format
|
|
||||||
|
|
||||||
@par Formats (:format)
|
|
||||||
xml, json, rss, atom
|
|
||||||
|
|
||||||
@par HTTP Method(s)
|
|
||||||
GET
|
|
||||||
|
|
||||||
@par Requires Authentication
|
|
||||||
No
|
|
||||||
|
|
||||||
@param since_id (Optional) Returns only statuses with an ID greater
|
|
||||||
than (that is, more recent than) the specified ID.
|
|
||||||
@param max_id (Optional) Returns only statuses with an ID less than
|
|
||||||
(that is, older than) or equal to the specified ID.
|
|
||||||
@param count (Optional) Specifies the number of statuses to retrieve.
|
|
||||||
@param page (Optional) Specifies the page of results to retrieve.
|
|
||||||
|
|
||||||
@sa @ref apiroot
|
|
||||||
|
|
||||||
@subsection usagenotes Usage notes
|
|
||||||
@li The URL pattern is relative to the @ref apiroot.
|
|
||||||
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
|
|
||||||
to encode the latitude and longitude (see example response below <georss:point>).
|
|
||||||
|
|
||||||
@subsection exampleusage Example usage
|
|
||||||
|
|
||||||
@verbatim
|
|
||||||
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
|
|
||||||
@endverbatim
|
|
||||||
|
|
||||||
@subsection exampleresponse Example response
|
|
||||||
|
|
||||||
@verbatim
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<statuses type="array">
|
|
||||||
<status>
|
|
||||||
<text>@skwashd oh, commbank reenabled me super quick both times. but disconcerting when you don't expect it though</text>
|
|
||||||
<truncated>false</truncated>
|
|
||||||
<created_at>Sat Apr 17 00:49:12 +0000 2010</created_at>
|
|
||||||
<in_reply_to_status_id>28838393</in_reply_to_status_id>
|
|
||||||
<source>xmpp</source>
|
|
||||||
<id>28838456</id>
|
|
||||||
<in_reply_to_user_id>39303</in_reply_to_user_id>
|
|
||||||
<in_reply_to_screen_name>skwashd</in_reply_to_screen_name>
|
|
||||||
<geo></geo>
|
|
||||||
<favorited>false</favorited>
|
|
||||||
<user>
|
|
||||||
<id>44517</id>
|
|
||||||
<name>joshua may</name>
|
|
||||||
<screen_name>notjosh</screen_name>
|
|
||||||
<location></location>
|
|
||||||
<description></description>
|
|
||||||
<profile_image_url>http://avatar.identi.ca/44517-48-20090321004106.jpeg</profile_image_url>
|
|
||||||
<url></url>
|
|
||||||
<protected>false</protected>
|
|
||||||
<followers_count>17</followers_count>
|
|
||||||
<profile_background_color></profile_background_color>
|
|
||||||
<profile_text_color></profile_text_color>
|
|
||||||
<profile_link_color></profile_link_color>
|
|
||||||
<profile_sidebar_fill_color></profile_sidebar_fill_color>
|
|
||||||
<profile_sidebar_border_color></profile_sidebar_border_color>
|
|
||||||
<friends_count>20</friends_count>
|
|
||||||
<created_at>Sat Mar 21 00:40:25 +0000 2009</created_at>
|
|
||||||
<favourites_count>0</favourites_count>
|
|
||||||
<utc_offset>0</utc_offset>
|
|
||||||
<time_zone>UTC</time_zone>
|
|
||||||
<profile_background_image_url></profile_background_image_url>
|
|
||||||
<profile_background_tile>false</profile_background_tile>
|
|
||||||
<statuses_count>100</statuses_count>
|
|
||||||
<following>false</following>
|
|
||||||
<notifications>false</notifications>
|
|
||||||
</user>
|
|
||||||
</status>
|
|
||||||
[....]
|
|
||||||
</statuses>
|
|
||||||
@endverbatim
|
|
||||||
*/
|
|
||||||
class ApiTimelinePublicAndExternalAction extends ApiPrivateAuthAction
|
class ApiTimelinePublicAndExternalAction extends ApiPrivateAuthAction
|
||||||
{
|
{
|
||||||
var $notices = null;
|
var $notices = null;
|
||||||
|
|
|
@ -189,7 +189,9 @@ class QvitterAction extends ApiAction
|
||||||
color:#0084B4;/*COLOREND*/
|
color:#0084B4;/*COLOREND*/
|
||||||
}
|
}
|
||||||
.topbar .global-nav,
|
.topbar .global-nav,
|
||||||
.menu-container {
|
.menu-container,
|
||||||
|
#unseen-notifications,
|
||||||
|
.stream-item.notification .not-seen {
|
||||||
background-color:#0084B4;/*BACKGROUNDCOLOREND*/
|
background-color:#0084B4;/*BACKGROUNDCOLOREND*/
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -278,7 +280,14 @@ class QvitterAction extends ApiAction
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="page-container">
|
<div id="page-container">
|
||||||
<div class="front-welcome-text">
|
<?php
|
||||||
|
|
||||||
|
$site_notice = common_config('site', 'notice');
|
||||||
|
if(!empty($site_notice)) {
|
||||||
|
print '<div id="site-notice">'.common_config('site', 'notice').'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?><div class="front-welcome-text">
|
||||||
<h1></h1>
|
<h1></h1>
|
||||||
<p></p>
|
<p></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -343,6 +352,7 @@ class QvitterAction extends ApiAction
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-container">
|
<div class="menu-container">
|
||||||
<a class="stream-selection friends-timeline" data-stream-header="" data-stream-name="qvitter/statuses/friends_timeline.json"><i class="chev-right"></i></a>
|
<a class="stream-selection friends-timeline" data-stream-header="" data-stream-name="qvitter/statuses/friends_timeline.json"><i class="chev-right"></i></a>
|
||||||
|
<a class="stream-selection notifications" data-stream-header="" data-stream-name="qvitter/statuses/notifications.json"><span id="unseen-notifications"></span><i class="chev-right"></i></a>
|
||||||
<a class="stream-selection mentions" data-stream-header="" data-stream-name="qvitter/statuses/mentions.json"><i class="chev-right"></i></a>
|
<a class="stream-selection mentions" data-stream-header="" data-stream-name="qvitter/statuses/mentions.json"><i class="chev-right"></i></a>
|
||||||
<a class="stream-selection my-timeline" data-stream-header="@statuses/user_timeline.json" data-stream-name="statuses/user_timeline.json"><i class="chev-right"></i></a>
|
<a class="stream-selection my-timeline" data-stream-header="@statuses/user_timeline.json" data-stream-name="statuses/user_timeline.json"><i class="chev-right"></i></a>
|
||||||
<a class="stream-selection favorites" data-stream-header="" data-stream-name="favorites.json"><i class="chev-right"></i></a>
|
<a class="stream-selection favorites" data-stream-header="" data-stream-name="favorites.json"><i class="chev-right"></i></a>
|
||||||
|
@ -350,6 +360,7 @@ class QvitterAction extends ApiAction
|
||||||
<a href="<?php print $instanceurl ?>main/all" class="stream-selection public-and-external-timeline" data-stream-header="" data-stream-name="statuses/public_and_external_timeline.json"><i class="chev-right"></i></a>
|
<a href="<?php print $instanceurl ?>main/all" class="stream-selection public-and-external-timeline" data-stream-header="" data-stream-name="statuses/public_and_external_timeline.json"><i class="chev-right"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-container" id="history-container"></div>
|
<div class="menu-container" id="history-container"></div>
|
||||||
|
<div id="qvitter-notice"><?php print common_config('site', 'qvitternotice'); ?></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="feed">
|
<div id="feed">
|
||||||
<div id="feed-header">
|
<div id="feed-header">
|
||||||
|
@ -364,7 +375,7 @@ class QvitterAction extends ApiAction
|
||||||
|
|
||||||
<div id="footer"></div>
|
<div id="footer"></div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery-2.0.2.min.js"></script>
|
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery-2.1.1.min.js"></script>
|
||||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery-ui-1.10.3.min.js"></script>
|
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery-ui-1.10.3.min.js"></script>
|
||||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery.easing.1.3.js"></script>
|
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery.easing.1.3.js"></script>
|
||||||
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery.minicolors.min.js"></script>
|
<script type="text/javascript" src="<?php print $qvitterpath; ?>js/lib/jquery.minicolors.min.js"></script>
|
||||||
|
|
203
actions/qvitteradminsettings.php
Normal file
203
actions/qvitteradminsettings.php
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· Q V I T T E R ·
|
||||||
|
· ·
|
||||||
|
· http://github.com/hannesmannerheim/qvitter ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· <o) ·
|
||||||
|
· /_//// ·
|
||||||
|
· (____/ ·
|
||||||
|
· (o< ·
|
||||||
|
· o> \\\\_\ ·
|
||||||
|
· \\) \____) ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· ·
|
||||||
|
· 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 ·
|
||||||
|
· your option) any later version. ·
|
||||||
|
· ·
|
||||||
|
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
|
||||||
|
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
|
||||||
|
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
|
||||||
|
· more details. ·
|
||||||
|
· ·
|
||||||
|
· You should have received a copy of the GNU Affero General Public License ·
|
||||||
|
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
|
||||||
|
· ·
|
||||||
|
· Contact h@nnesmannerhe.im if you have any questions. ·
|
||||||
|
· ·
|
||||||
|
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
|
||||||
|
|
||||||
|
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';
|
||||||
|
|
||||||
|
|
||||||
|
class QvitterAdminSettingsAction extends AdminPanelAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the page title
|
||||||
|
*
|
||||||
|
* @return string page title
|
||||||
|
*/
|
||||||
|
function title()
|
||||||
|
{
|
||||||
|
// TRANS: Page title for site-wide notice tab in admin panel.
|
||||||
|
return _('Qvitter Sidebar Notice');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructions for using this form.
|
||||||
|
*
|
||||||
|
* @return string instructions
|
||||||
|
*/
|
||||||
|
function getInstructions()
|
||||||
|
{
|
||||||
|
// TRANS: Instructions for site-wide notice tab in admin panel.
|
||||||
|
return _('Edit notice in Qvitter\'s sidebar');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the site notice admin panel form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function showForm()
|
||||||
|
{
|
||||||
|
$form = new QvitterNoticeAdminPanelForm($this);
|
||||||
|
$form->show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save settings from the form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function saveSettings()
|
||||||
|
{
|
||||||
|
$qvitterNotice = $this->trimmed('qvitter-notice');
|
||||||
|
|
||||||
|
// assert(all values are valid);
|
||||||
|
// This throws an exception on validation errors
|
||||||
|
|
||||||
|
$this->validate($qvitterNotice);
|
||||||
|
|
||||||
|
$config = new Config();
|
||||||
|
|
||||||
|
$result = Config::save('site', 'qvitternotice', $qvitterNotice);
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
// TRANS: Server error displayed when saving a sidebar notice was impossible.
|
||||||
|
$this->ServerError(_('Unable to save qvitter sidebar notice.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate(&$qvitterNotice)
|
||||||
|
{
|
||||||
|
// Validate notice text
|
||||||
|
|
||||||
|
if (mb_strlen($qvitterNotice) > 255) {
|
||||||
|
$this->clientError(
|
||||||
|
// TRANS: Client error displayed when a sidebar notice was longer than allowed.
|
||||||
|
_('Maximum length for the sidebar notice is 255 characters.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scrub HTML input
|
||||||
|
|
||||||
|
$config = array(
|
||||||
|
'safe' => 1,
|
||||||
|
'deny_attribute' => 'on*'
|
||||||
|
);
|
||||||
|
|
||||||
|
$qvitterNotice = htmLawed($qvitterNotice, $config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class QvitterNoticeAdminPanelForm extends AdminForm
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ID of the form
|
||||||
|
*
|
||||||
|
* @return int ID of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function id()
|
||||||
|
{
|
||||||
|
return 'form_qvitter_notice_admin_panel';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class of the form
|
||||||
|
*
|
||||||
|
* @return string class of the form
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formClass()
|
||||||
|
{
|
||||||
|
return 'form_settings';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action of the form
|
||||||
|
*
|
||||||
|
* @return string URL of the action
|
||||||
|
*/
|
||||||
|
|
||||||
|
function action()
|
||||||
|
{
|
||||||
|
return common_local_url('qvitteradminsettings');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data elements of the form
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formData()
|
||||||
|
{
|
||||||
|
$this->out->elementStart('ul', 'form_data');
|
||||||
|
|
||||||
|
$this->out->elementStart('li');
|
||||||
|
$this->out->textarea(
|
||||||
|
'qvitter-notice',
|
||||||
|
// TRANS: Label for sidebar notice text field in admin panel.
|
||||||
|
_('Qvitter sidebar notice text'),
|
||||||
|
common_config('site', 'qvitternotice'),
|
||||||
|
// TRANS: Tooltip for sidebar notice text field in admin panel.
|
||||||
|
_('Qvitter\'s sidebar notice text (255 characters maximum; HTML allowed)')
|
||||||
|
);
|
||||||
|
$this->out->elementEnd('li');
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action elements
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formActions()
|
||||||
|
{
|
||||||
|
$this->out->submit(
|
||||||
|
'submit',
|
||||||
|
// TRANS: Button text for saving sidebar notice in admin panel.
|
||||||
|
_m('BUTTON','Save'),
|
||||||
|
'submit',
|
||||||
|
null,
|
||||||
|
// TRANS: Button title to save sidebar notice in admin panel.
|
||||||
|
_('Save sidebar notice.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
85
classes/NotificationStream.php
Normal file
85
classes/NotificationStream.php
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Notification stream
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('GNUSOCIAL') && !defined('STATUSNET')) { exit(1); }
|
||||||
|
|
||||||
|
class NotificationStream
|
||||||
|
{
|
||||||
|
protected $target = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Profile $target Profile to get a stream for
|
||||||
|
*/
|
||||||
|
function __construct(Profile $target)
|
||||||
|
{
|
||||||
|
$this->target = $target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get IDs in a range
|
||||||
|
*
|
||||||
|
* @param int $offset Offset from start
|
||||||
|
* @param int $limit Limit of number to get
|
||||||
|
* @param int $since_id Since this notice
|
||||||
|
* @param int $max_id Before this notice
|
||||||
|
*
|
||||||
|
* @return Array IDs found
|
||||||
|
*/
|
||||||
|
function getNotificationIds($offset, $limit, $since_id, $max_id)
|
||||||
|
{
|
||||||
|
$notification = new QvitterNotification();
|
||||||
|
$notification->selectAdd();
|
||||||
|
$notification->selectAdd('id');
|
||||||
|
$notification->whereAdd(sprintf('qvitternotification.to_profile_id = "%s"', $notification->escape($this->target->id)));
|
||||||
|
$notification->whereAdd(sprintf('qvitternotification.created > "%s"', $notification->escape($this->target->created)));
|
||||||
|
$notification->limit($offset, $limit);
|
||||||
|
$notification->orderBy('qvitternotification.created DESC');
|
||||||
|
|
||||||
|
QvitterNotification::addWhereSinceId($notification, $since_id);
|
||||||
|
QvitterNotification::addWhereMaxId($notification, $max_id);
|
||||||
|
|
||||||
|
if (!$notification->find()) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = $notification->fetchAll('id');
|
||||||
|
|
||||||
|
return $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNotifications($offset, $limit, $sinceId, $maxId)
|
||||||
|
{
|
||||||
|
|
||||||
|
$all = array();
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
$ids = $this->getNotificationIds($offset, $limit, $sinceId, $maxId);
|
||||||
|
|
||||||
|
$notifications = QvitterNotification::pivotGet('id', $ids);
|
||||||
|
|
||||||
|
// By default, takes out false values
|
||||||
|
|
||||||
|
$notifications = array_filter($notifications);
|
||||||
|
|
||||||
|
$all = array_merge($all, $notifications);
|
||||||
|
|
||||||
|
if (count($notifications < count($ids))) {
|
||||||
|
$offset += $limit;
|
||||||
|
$limit -= count($notifications);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (count($notifications) < count($ids) && count($ids) > 0);
|
||||||
|
|
||||||
|
return new ArrayWrapper($all);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
152
classes/QvitterNotification.php
Normal file
152
classes/QvitterNotification.php
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Table Definition for reply
|
||||||
|
*/
|
||||||
|
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||||
|
|
||||||
|
class QvitterNotification extends Managed_DataObject
|
||||||
|
{
|
||||||
|
###START_AUTOCODE
|
||||||
|
/* the code below is auto generated do not remove the above tag */
|
||||||
|
|
||||||
|
public $__table = 'qvitternotification'; // table name
|
||||||
|
public $id; // int(4) primary_key not_null
|
||||||
|
public $to_profile_id; // int(4) primary_key not_null
|
||||||
|
public $from_profile_id; // int(4) primary_key not_null
|
||||||
|
public $type; // varchar(7)
|
||||||
|
public $notice_id; // int(4) primary_key not_null
|
||||||
|
public $date; // datetime multiple_key not_null default_0000-00-00%2000%3A00%3A00
|
||||||
|
|
||||||
|
/* the code above is auto generated do not remove the tag below */
|
||||||
|
###END_AUTOCODE
|
||||||
|
|
||||||
|
public static function schemaDef()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'fields' => array(
|
||||||
|
'id' => array('type' => 'serial', 'not null' => true),
|
||||||
|
'to_profile_id' => array('type' => 'int', 'description' => 'the profile being notified'),
|
||||||
|
'from_profile_id' => array('type' => 'int', 'description' => 'the profile that is notifying'),
|
||||||
|
'ntype' => array('type' => 'varchar', 'length' => 7, 'description' => 'reply, like, mention or follow'),
|
||||||
|
'notice_id' => array('type' => 'int', 'description' => 'id for the reply or mention or notice being faved'),
|
||||||
|
'is_seen' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'if the notification has been seen'),
|
||||||
|
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created')
|
||||||
|
),
|
||||||
|
'primary key' => array('id')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for record insertion to update related caches
|
||||||
|
*/
|
||||||
|
function insert()
|
||||||
|
{
|
||||||
|
$result = parent::insert();
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
self::blow('qvitternotification:stream:%d', $this->to_profile_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the creation timestamp for a given notice ID, even
|
||||||
|
* if it's been deleted.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return mixed string recorded creation timestamp, or false if can't be found
|
||||||
|
*/
|
||||||
|
public static function getAsTimestamp($id)
|
||||||
|
{
|
||||||
|
if (!$id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notice = QvitterNotification::getKV('id', $id);
|
||||||
|
if ($notice) {
|
||||||
|
return $notice->created;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an SQL 'where' fragment for timestamp-based sorting from a since_id
|
||||||
|
* parameter, matching notices posted after the given one (exclusive).
|
||||||
|
*
|
||||||
|
* If the referenced notice can't be found, will return false.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param string $idField
|
||||||
|
* @param string $createdField
|
||||||
|
* @return mixed string or false if no match
|
||||||
|
*/
|
||||||
|
public static function whereSinceId($id, $idField='id', $createdField='created')
|
||||||
|
{
|
||||||
|
$since = QvitterNotification::getAsTimestamp($id);
|
||||||
|
if ($since) {
|
||||||
|
return sprintf("($createdField = '%s' and $idField > %d) or ($createdField > '%s')", $since, $id, $since);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an SQL 'where' fragment for timestamp-based sorting from a since_id
|
||||||
|
* parameter, matching notices posted after the given one (exclusive), and
|
||||||
|
* if necessary add it to the data object's query.
|
||||||
|
*
|
||||||
|
* @param DB_DataObject $obj
|
||||||
|
* @param int $id
|
||||||
|
* @param string $idField
|
||||||
|
* @param string $createdField
|
||||||
|
* @return mixed string or false if no match
|
||||||
|
*/
|
||||||
|
public static function addWhereSinceId(DB_DataObject $obj, $id, $idField='id', $createdField='created')
|
||||||
|
{
|
||||||
|
$since = self::whereSinceId($id, $idField, $createdField);
|
||||||
|
if ($since) {
|
||||||
|
$obj->whereAdd($since);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an SQL 'where' fragment for timestamp-based sorting from a max_id
|
||||||
|
* parameter, matching notices posted before the given one (inclusive).
|
||||||
|
*
|
||||||
|
* If the referenced notice can't be found, will return false.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param string $idField
|
||||||
|
* @param string $createdField
|
||||||
|
* @return mixed string or false if no match
|
||||||
|
*/
|
||||||
|
public static function whereMaxId($id, $idField='id', $createdField='created')
|
||||||
|
{
|
||||||
|
$max = QvitterNotification::getAsTimestamp($id);
|
||||||
|
if ($max) {
|
||||||
|
return sprintf("($createdField < '%s') or ($createdField = '%s' and $idField <= %d)", $max, $max, $id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an SQL 'where' fragment for timestamp-based sorting from a max_id
|
||||||
|
* parameter, matching notices posted before the given one (inclusive), and
|
||||||
|
* if necessary add it to the data object's query.
|
||||||
|
*
|
||||||
|
* @param DB_DataObject $obj
|
||||||
|
* @param int $id
|
||||||
|
* @param string $idField
|
||||||
|
* @param string $createdField
|
||||||
|
* @return mixed string or false if no match
|
||||||
|
*/
|
||||||
|
public static function addWhereMaxId(DB_DataObject $obj, $id, $idField='id', $createdField='created')
|
||||||
|
{
|
||||||
|
$max = self::whereMaxId($id, $idField, $createdField);
|
||||||
|
if ($max) {
|
||||||
|
$obj->whereAdd($max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
153
css/qvitter.css
153
css/qvitter.css
|
@ -409,7 +409,7 @@ body.rtl .dropdown-menu li:not(.dropdown-caret) {
|
||||||
.dropdown-menu.quitter-settings li.language {
|
.dropdown-menu.quitter-settings li.language {
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#birds-top {
|
#birds-top {
|
||||||
background-position: -193px -3px;
|
background-position: -193px -3px;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -436,7 +436,8 @@ body.rtl .dropdown-menu li:not(.dropdown-caret) {
|
||||||
unicode-bidi: bidi-override;
|
unicode-bidi: bidi-override;
|
||||||
}
|
}
|
||||||
|
|
||||||
.front-welcome-text {
|
.front-welcome-text,
|
||||||
|
#site-notice {
|
||||||
color: #EEEEEE;
|
color: #EEEEEE;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
|
@ -453,6 +454,26 @@ body.rtl .front-welcome-text {
|
||||||
text-align:right;
|
text-align:right;
|
||||||
font-family:Tahoma,Arial,sans-serif;
|
font-family:Tahoma,Arial,sans-serif;
|
||||||
}
|
}
|
||||||
|
#site-notice{
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
#qvitter-notice {
|
||||||
|
text-shadow:none;
|
||||||
|
color:#fff;
|
||||||
|
font-size:11px;
|
||||||
|
padding:10px;
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
#qvitter-notice a {
|
||||||
|
color:#fff;
|
||||||
|
opacity:0.5;
|
||||||
|
line-height:17px;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
#qvitter-notice a:hover {
|
||||||
|
opacity:0.8;
|
||||||
|
}
|
||||||
|
|
||||||
.front-welcome-text h1 {
|
.front-welcome-text h1 {
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
|
@ -992,7 +1013,32 @@ button#submit-login:hover {
|
||||||
}
|
}
|
||||||
#history-container a:hover .chev-right:hover {
|
#history-container a:hover .chev-right:hover {
|
||||||
background-position:-40px -508px;
|
background-position:-40px -508px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-container a.notifications {
|
||||||
|
line-height:32px;
|
||||||
|
padding:0 12px;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#unseen-notifications {
|
||||||
|
display:block;
|
||||||
|
position:absolute;
|
||||||
|
right:0px;
|
||||||
|
top:0;
|
||||||
|
width:24px;
|
||||||
|
height:24px;
|
||||||
|
line-height:24px;
|
||||||
|
border-radius:12px;
|
||||||
|
color:#fff;
|
||||||
|
text-shadow:none;
|
||||||
|
margin:4px 5px;
|
||||||
|
z-index:10;
|
||||||
|
display:none;
|
||||||
|
text-align:center;
|
||||||
|
font-weight:normal;
|
||||||
|
}
|
||||||
|
|
||||||
#history-container {
|
#history-container {
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
@ -1204,6 +1250,7 @@ button#submit-login:hover {
|
||||||
-o-transition: opacity 0.1s ease, height 0s linear, margin 0.1s ease;
|
-o-transition: opacity 0.1s ease, height 0s linear, margin 0.1s ease;
|
||||||
transition: opacity 0.1s ease, height 0s linear, margin 0.1s ease;
|
transition: opacity 0.1s ease, height 0s linear, margin 0.1s ease;
|
||||||
height:auto;
|
height:auto;
|
||||||
|
/* position:relative; */
|
||||||
}
|
}
|
||||||
.stream-item.hidden {
|
.stream-item.hidden {
|
||||||
display:none;
|
display:none;
|
||||||
|
@ -1230,6 +1277,70 @@ button#submit-login:hover {
|
||||||
.stream-item.conversation .queet:hover {
|
.stream-item.conversation .queet:hover {
|
||||||
background-color:#F6F6F6;
|
background-color:#F6F6F6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stream-item.notification .not-seen {
|
||||||
|
position:absolute;
|
||||||
|
left:-5px;
|
||||||
|
top:50%;
|
||||||
|
margin-top:-5px;
|
||||||
|
width:10px;
|
||||||
|
height:10px;
|
||||||
|
border-radius:5px;
|
||||||
|
z-index:10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stream-item.notification.repeat .dogear,
|
||||||
|
.stream-item.notification.like .dogear {
|
||||||
|
display:block;
|
||||||
|
left: 36px;
|
||||||
|
top: 7px;
|
||||||
|
z-index: 10;
|
||||||
|
width:24px;
|
||||||
|
height:24px;
|
||||||
|
}
|
||||||
|
.stream-item.notification.repeat .dogear {
|
||||||
|
background-position:-70px -1072px;
|
||||||
|
}
|
||||||
|
.stream-item.notification.like .dogear {
|
||||||
|
background-position:-115px -1075px;
|
||||||
|
}
|
||||||
|
.stream-item.notification.follow .queet,
|
||||||
|
.stream-item.notification.repeat .queet,
|
||||||
|
.stream-item.notification.like .queet {
|
||||||
|
min-height:37px;
|
||||||
|
cursor:default;
|
||||||
|
}
|
||||||
|
.stream-item.notification.follow .queet .queet-content,
|
||||||
|
.stream-item.notification.repeat .queet .queet-content,
|
||||||
|
.stream-item.notification.like .queet .queet-content {
|
||||||
|
cursor:default;
|
||||||
|
}
|
||||||
|
.stream-item.notification.follow .queet:hover,
|
||||||
|
.stream-item.notification.repeat .queet:hover,
|
||||||
|
.stream-item.notification.like .queet:hover {
|
||||||
|
background-color:transparent;
|
||||||
|
}
|
||||||
|
.stream-item.notification.follow a.account-group img.avatar,
|
||||||
|
.stream-item.notification.repeat a.account-group img.avatar,
|
||||||
|
.stream-item.notification.like a.account-group img.avatar {
|
||||||
|
width:24px;
|
||||||
|
height:24px;
|
||||||
|
left:36px;
|
||||||
|
top:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stream-item.notification .small-grey-notice,
|
||||||
|
.stream-item.notification .small-grey-notice a {
|
||||||
|
color:#999;
|
||||||
|
}
|
||||||
|
.stream-item.notification .small-grey-notice a:hover {
|
||||||
|
color:#333;
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
.stream-item.notification .stream-item-header {
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
|
||||||
.show-full-conversation {
|
.show-full-conversation {
|
||||||
float:right;
|
float:right;
|
||||||
font-style:italic;
|
font-style:italic;
|
||||||
|
@ -1281,6 +1392,14 @@ button#submit-login:hover {
|
||||||
border-radius:0 0 6px 6px;
|
border-radius:0 0 6px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expanded-content {
|
||||||
|
-webkit-transition: height 0s linear;
|
||||||
|
-moz-transition: height 0s linear;
|
||||||
|
-o-transition: height 0s linear;
|
||||||
|
transition: height 0s linear;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
body.rtl .queet.rtl .expanded-content {
|
body.rtl .queet.rtl .expanded-content {
|
||||||
direction:rtl;
|
direction:rtl;
|
||||||
}
|
}
|
||||||
|
@ -3718,6 +3837,12 @@ body.rtl #feed-header-inner h2 {
|
||||||
|
|
||||||
@media (max-width: 866px) {
|
@media (max-width: 866px) {
|
||||||
|
|
||||||
|
#site-notice,
|
||||||
|
#qvitter-notice {
|
||||||
|
display:none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#new-queets-bar-container {
|
#new-queets-bar-container {
|
||||||
height:77px;
|
height:77px;
|
||||||
}
|
}
|
||||||
|
@ -4060,6 +4185,7 @@ body.rtl #feed-header-inner h2 {
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
.menu-container a.favorites,
|
.menu-container a.favorites,
|
||||||
|
.menu-container a.mentions,
|
||||||
.menu-container a.public-and-external-timeline {
|
.menu-container a.public-and-external-timeline {
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
@ -4071,7 +4197,7 @@ body.rtl #feed-header-inner h2 {
|
||||||
font-size:0;
|
font-size:0;
|
||||||
color:transparent;
|
color:transparent;
|
||||||
height:55px;
|
height:55px;
|
||||||
padding:0;
|
padding:0 !important;
|
||||||
margin:0;
|
margin:0;
|
||||||
border-radius:0 0 0 0 !important;
|
border-radius:0 0 0 0 !important;
|
||||||
background-image: url("../img/sprite.png?v=2");
|
background-image: url("../img/sprite.png?v=2");
|
||||||
|
@ -4098,7 +4224,7 @@ body.rtl #feed-header-inner h2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.stream-selection.friends-timeline:after,
|
.stream-selection.friends-timeline:after,
|
||||||
.stream-selection.mentions:after,
|
.stream-selection.notifications:after,
|
||||||
.stream-selection.my-timeline:after,
|
.stream-selection.my-timeline:after,
|
||||||
.stream-selection.public-timeline:after {
|
.stream-selection.public-timeline:after {
|
||||||
content: "";
|
content: "";
|
||||||
|
@ -4115,7 +4241,7 @@ body.rtl #feed-header-inner h2 {
|
||||||
.stream-selection.friends-timeline:after {
|
.stream-selection.friends-timeline:after {
|
||||||
background-position:0px -861px ;
|
background-position:0px -861px ;
|
||||||
}
|
}
|
||||||
.stream-selection.mentions:after {
|
.stream-selection.notifications:after {
|
||||||
background-position:-78px -861px ;
|
background-position:-78px -861px ;
|
||||||
}
|
}
|
||||||
.stream-selection.my-timeline:after {
|
.stream-selection.my-timeline:after {
|
||||||
|
@ -4249,8 +4375,12 @@ body.rtl #feed-header-inner h2 {
|
||||||
border-top: 1px solid #E8E8E8;
|
border-top: 1px solid #E8E8E8;
|
||||||
border-bottom: 1px solid #E8E8E8;
|
border-bottom: 1px solid #E8E8E8;
|
||||||
height:45px;
|
height:45px;
|
||||||
margin-top:20px;
|
margin-top:9px;
|
||||||
}
|
}
|
||||||
|
.queet-content {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
padding-bottom:0;
|
||||||
|
}
|
||||||
/* .stream-item.collapsing > .queet ul.queet-actions {
|
/* .stream-item.collapsing > .queet ul.queet-actions {
|
||||||
display:none !important;
|
display:none !important;
|
||||||
} */
|
} */
|
||||||
|
@ -4289,9 +4419,6 @@ body.rtl #feed-header-inner h2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.queet ul.stats {
|
.queet ul.stats {
|
||||||
border-top: 0 none;
|
|
||||||
margin-left:-63px;
|
|
||||||
margin-top:0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.queet ul.stats li.rq-count a,
|
.queet ul.stats li.rq-count a,
|
||||||
|
@ -4302,7 +4429,11 @@ body.rtl #feed-header-inner h2 {
|
||||||
.queet ul.stats li:first-child a {
|
.queet ul.stats li:first-child a {
|
||||||
padding-left:0 !important;
|
padding-left:0 !important;
|
||||||
}
|
}
|
||||||
.client-and-actions {
|
.expanded-content {
|
||||||
|
-webkit-transition: none !important;
|
||||||
|
-moz-transition: none !important;
|
||||||
|
-o-transition: none !important;
|
||||||
|
transition: none !important;
|
||||||
margin-left:-63px;
|
margin-left:-63px;
|
||||||
}
|
}
|
||||||
.client-and-actions .permalink-link {
|
.client-and-actions .permalink-link {
|
||||||
|
|
BIN
img/sprite.png
BIN
img/sprite.png
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 60 KiB |
3117
img/sprite.png.ai
3117
img/sprite.png.ai
File diff suppressed because one or more lines are too long
|
@ -326,4 +326,53 @@ function getFavsOrRequeetsForQueet(apiaction,qid,actionOnSuccess) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ·
|
||||||
|
·
|
||||||
|
· Check for unseen notifications
|
||||||
|
·
|
||||||
|
· @param actionOnSuccess: callback function
|
||||||
|
·
|
||||||
|
· · · · · · · · · */
|
||||||
|
|
||||||
|
function checkForNewNotifications() {
|
||||||
|
$.ajax({ url: window.apiRoot + "qvitter/newnotifications.json",
|
||||||
|
type: "GET",
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
|
||||||
|
if(data.length == 0) {
|
||||||
|
$('#unseen-notifications').hide();
|
||||||
|
document.title = window.siteTitle;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
var totNotif = 0;
|
||||||
|
$.each(data,function(k,v){
|
||||||
|
totNotif = totNotif + parseInt(v,10);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(totNotif>0) {
|
||||||
|
$('#unseen-notifications').html(totNotif);
|
||||||
|
document.title = window.siteTitle + ' (' + totNotif + ')'; // update html page title
|
||||||
|
$('#unseen-notifications').show();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#unseen-notifications').hide();
|
||||||
|
document.title = window.siteTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
$('#unseen-notifications').hide();
|
||||||
|
document.title = window.siteTitle;
|
||||||
|
remove_spinner();
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,7 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
|
|
||||||
// halt interval that checks for new queets
|
// halt interval that checks for new queets
|
||||||
window.clearInterval(checkForNewQueetsInterval);
|
window.clearInterval(checkForNewQueetsInterval);
|
||||||
|
window.clearInterval(checkForNewNotificationsInterval);
|
||||||
|
|
||||||
display_spinner();
|
display_spinner();
|
||||||
|
|
||||||
|
@ -335,6 +336,7 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
// if this is one of the default streams, get header from DOM
|
// if this is one of the default streams, get header from DOM
|
||||||
else if(stream == 'qvitter/statuses/friends_timeline.json'
|
else if(stream == 'qvitter/statuses/friends_timeline.json'
|
||||||
|| stream == 'qvitter/statuses/mentions.json'
|
|| stream == 'qvitter/statuses/mentions.json'
|
||||||
|
|| stream == 'qvitter/statuses/notifications.json'
|
||||||
|| stream == 'favorites.json'
|
|| stream == 'favorites.json'
|
||||||
|| stream == 'statuses/public_timeline.json'
|
|| stream == 'statuses/public_timeline.json'
|
||||||
|| stream == 'statuses/public_and_external_timeline.json') {
|
|| stream == 'statuses/public_and_external_timeline.json') {
|
||||||
|
@ -354,6 +356,11 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
var defaultStreamName = stream;
|
var defaultStreamName = stream;
|
||||||
var streamHeader = '#' + stream.substring(stream.indexOf('/timeline/')+10,stream.indexOf('.json'));
|
var streamHeader = '#' + stream.substring(stream.indexOf('/timeline/')+10,stream.indexOf('.json'));
|
||||||
}
|
}
|
||||||
|
// if this is a notice stream
|
||||||
|
else if(stream.substring(0,14) == 'statuses/show/') {
|
||||||
|
var defaultStreamName = stream;
|
||||||
|
var streamHeader = 'notice/' + stream.substring(stream.indexOf('/show/')+6,stream.indexOf('.json'));
|
||||||
|
}
|
||||||
// if this is a search stream
|
// if this is a search stream
|
||||||
else if(stream.substring(0,11) == 'search.json') {
|
else if(stream.substring(0,11) == 'search.json') {
|
||||||
var defaultStreamName = stream;
|
var defaultStreamName = stream;
|
||||||
|
@ -362,10 +369,10 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
|
|
||||||
// set the h2 header in the feed
|
// set the h2 header in the feed
|
||||||
if(stream.substring(0,23) == 'statuses/followers.json') {
|
if(stream.substring(0,23) == 'statuses/followers.json') {
|
||||||
var h2FeedHeader = window.sL.followers;
|
var h2FeedHeader = '<div class="queet-streams"><a class="queet-stream following">' + window.sL.following + '</a> / </div>' + window.sL.followers;
|
||||||
}
|
}
|
||||||
else if(stream.substring(0,21) == 'statuses/friends.json') {
|
else if(stream.substring(0,21) == 'statuses/friends.json') {
|
||||||
var h2FeedHeader = window.sL.following;
|
var h2FeedHeader = window.sL.following + '<div class="queet-streams">/ <a class="queet-stream followers">' + window.sL.followers + '</a></div>';
|
||||||
}
|
}
|
||||||
else if(stream.substring(0,40) == 'statuses/user_timeline.json?screen_name=') {
|
else if(stream.substring(0,40) == 'statuses/user_timeline.json?screen_name=') {
|
||||||
var h2FeedHeader = window.sL.notices + '<div class="queet-streams">/ <a class="queet-stream mentions">' + window.sL.mentions + '</a> / <a class="queet-stream favorites">' + window.sL.favoritesNoun +'</a></div>';
|
var h2FeedHeader = window.sL.notices + '<div class="queet-streams">/ <a class="queet-stream mentions">' + window.sL.mentions + '</a> / <a class="queet-stream favorites">' + window.sL.favoritesNoun +'</a></div>';
|
||||||
|
@ -428,6 +435,7 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
$('.stream-selection').removeClass('current');
|
$('.stream-selection').removeClass('current');
|
||||||
$('.stream-selection[data-stream-header="' + streamHeader + '"]').addClass('current');
|
$('.stream-selection[data-stream-header="' + streamHeader + '"]').addClass('current');
|
||||||
|
|
||||||
|
|
||||||
// if this is user's user feed, i.e. followers etc, we want a profile card, which we need to get from user_timeline since the users/show api action is broken (auth doesn't work)
|
// if this is user's user feed, i.e. followers etc, we want a profile card, which we need to get from user_timeline since the users/show api action is broken (auth doesn't work)
|
||||||
if(stream.substring(0,23) == 'statuses/followers.json'
|
if(stream.substring(0,23) == 'statuses/followers.json'
|
||||||
|| stream.substring(0,21) == 'statuses/friends.json'
|
|| stream.substring(0,21) == 'statuses/friends.json'
|
||||||
|
@ -454,7 +462,14 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
profileCardFromFirstObject(profile_data,thisUsersScreenName); // show profile card
|
profileCardFromFirstObject(profile_data,thisUsersScreenName); // show profile card
|
||||||
checkForNewQueetsInterval=window.setInterval(function(){checkForNewQueets()},window.timeBetweenPolling); // start interval again
|
|
||||||
|
// start checking for new queets again
|
||||||
|
window.clearInterval(checkForNewQueetsInterval);
|
||||||
|
window.clearInterval(checkForNewNotificationsInterval);
|
||||||
|
checkForNewQueetsInterval=window.setInterval(function(){checkForNewQueets()},window.timeBetweenPolling);
|
||||||
|
checkForNewNotificationsInterval=window.setInterval(function(){checkForNewNotifications()},window.timeBetweenPolling);
|
||||||
|
checkForNewNotifications();
|
||||||
|
|
||||||
remove_spinner();
|
remove_spinner();
|
||||||
$('#feed-body').html(''); // empty feed only now so the scrollers don't flicker on and off
|
$('#feed-body').html(''); // empty feed only now so the scrollers don't flicker on and off
|
||||||
$('#new-queets-bar').parent().addClass('hidden'); document.title = window.siteTitle; // hide new queets bar if it's visible there
|
$('#new-queets-bar').parent().addClass('hidden'); document.title = window.siteTitle; // hide new queets bar if it's visible there
|
||||||
|
@ -493,7 +508,19 @@ function setNewCurrentStream(stream,actionOnSuccess,setLocation) {
|
||||||
groupProfileCard(thisGroupAlias);
|
groupProfileCard(thisGroupAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForNewQueetsInterval=window.setInterval(function(){checkForNewQueets()},window.timeBetweenPolling); // start interval again
|
// start checking for new queets again
|
||||||
|
window.clearInterval(checkForNewQueetsInterval);
|
||||||
|
window.clearInterval(checkForNewNotificationsInterval);
|
||||||
|
checkForNewQueetsInterval=window.setInterval(function(){checkForNewQueets()},window.timeBetweenPolling);
|
||||||
|
if(window.currentStream != 'qvitter/statuses/notifications.json') { // don't check for notifications if this is the notifications page
|
||||||
|
checkForNewNotifications();
|
||||||
|
checkForNewNotificationsInterval=window.setInterval(function(){checkForNewNotifications()},window.timeBetweenPolling);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#unseen-notifications').hide();
|
||||||
|
document.title = window.siteTitle;
|
||||||
|
}
|
||||||
|
|
||||||
remove_spinner();
|
remove_spinner();
|
||||||
$('#feed-body').html(''); // empty feed only now so the scrollers don't flicker on and off
|
$('#feed-body').html(''); // empty feed only now so the scrollers don't flicker on and off
|
||||||
$('#new-queets-bar').parent().addClass('hidden'); document.title = window.siteTitle; // hide new queets bar if it's visible there
|
$('#new-queets-bar').parent().addClass('hidden'); document.title = window.siteTitle; // hide new queets bar if it's visible there
|
||||||
|
@ -547,6 +574,9 @@ function convertStreamToPath(stream) {
|
||||||
else if(stream == 'qvitter/statuses/mentions.json') {
|
else if(stream == 'qvitter/statuses/mentions.json') {
|
||||||
return window.loggedIn.screen_name + '/replies';
|
return window.loggedIn.screen_name + '/replies';
|
||||||
}
|
}
|
||||||
|
else if(stream == 'qvitter/statuses/notifications.json') {
|
||||||
|
return window.loggedIn.screen_name + '/notifications';
|
||||||
|
}
|
||||||
else if(stream == 'favorites.json') {
|
else if(stream == 'favorites.json') {
|
||||||
return window.loggedIn.screen_name + '/favorites';
|
return window.loggedIn.screen_name + '/favorites';
|
||||||
}
|
}
|
||||||
|
@ -564,9 +594,6 @@ function convertStreamToPath(stream) {
|
||||||
var screenName = stream.substring(stream.indexOf('=')+1);
|
var screenName = stream.substring(stream.indexOf('=')+1);
|
||||||
return screenName + '/all';
|
return screenName + '/all';
|
||||||
}
|
}
|
||||||
else if (stream == 'qvitter/statuses/mentions.json') {
|
|
||||||
return window.loggedIn.screen_name + '/replies';
|
|
||||||
}
|
|
||||||
else if(stream == 'statuses/public_timeline.json') {
|
else if(stream == 'statuses/public_timeline.json') {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -589,6 +616,10 @@ function convertStreamToPath(stream) {
|
||||||
var tagName = stream.substring(stream.indexOf('/timeline/')+10,stream.indexOf('.json'));
|
var tagName = stream.substring(stream.indexOf('/timeline/')+10,stream.indexOf('.json'));
|
||||||
return 'tag/' + tagName;
|
return 'tag/' + tagName;
|
||||||
}
|
}
|
||||||
|
else if(stream.substring(0,14) == 'statuses/show/') {
|
||||||
|
var noticeId = stream.substring(stream.indexOf('/show/')+6,stream.indexOf('.json'));
|
||||||
|
return 'notice/' + noticeId;
|
||||||
|
}
|
||||||
else if(stream.substring(0,11) == 'search.json') {
|
else if(stream.substring(0,11) == 'search.json') {
|
||||||
var searchTerms = stream.substring(stream.indexOf('?q=')+3);
|
var searchTerms = stream.substring(stream.indexOf('?q=')+3);
|
||||||
return 'search/notice?q=' + searchTerms;
|
return 'search/notice?q=' + searchTerms;
|
||||||
|
@ -662,6 +693,21 @@ function getStreamFromUrl() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {domain}/{screen_name}/notifications
|
||||||
|
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/notifications','')))) {
|
||||||
|
var userToStream = loc.replace('/','').replace('/notifications','');
|
||||||
|
if(userToStream.length>0) {
|
||||||
|
if(window.loggedIn.screen_name == userToStream) {
|
||||||
|
streamToSet = 'qvitter/statuses/notifications.json';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// not allowed for others than logged in user
|
||||||
|
window.location.replace(window.siteInstanceURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// {domain}/{screen_name}/favorites
|
// {domain}/{screen_name}/favorites
|
||||||
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/favorites','')))) {
|
else if ((/^[a-zA-Z0-9]+$/.test(loc.replace('/','').replace('/favorites','')))) {
|
||||||
|
@ -723,6 +769,15 @@ function getStreamFromUrl() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {domain}/notice/{notide_id}
|
||||||
|
else if (loc.indexOf('/notice/')>-1) {
|
||||||
|
var noticeToStream = loc.replace('/notice/','');
|
||||||
|
if(noticeToStream.length>0) {
|
||||||
|
streamToSet = 'statuses/show/' + noticeToStream + '.json';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// {domain}/group/{group}/members, {domain}/group/{group}/admins or {domain}/group/{group}
|
// {domain}/group/{group}/members, {domain}/group/{group}/admins or {domain}/group/{group}
|
||||||
else if (loc.indexOf('/group/')>-1) {
|
else if (loc.indexOf('/group/')>-1) {
|
||||||
|
|
||||||
|
@ -776,6 +831,10 @@ function expand_queet(q,doScrolling) {
|
||||||
var sel = getSelection().toString();
|
var sel = getSelection().toString();
|
||||||
|
|
||||||
if(!sel && !q.find('.queet-button').children('button').hasClass('enabled')) { // don't collapse if text is selected, or if queet has an active queet button
|
if(!sel && !q.find('.queet-button').children('button').hasClass('enabled')) { // don't collapse if text is selected, or if queet has an active queet button
|
||||||
|
|
||||||
|
// remove some things right away
|
||||||
|
q.find('.inline-reply-caret').remove();
|
||||||
|
|
||||||
q.addClass('collapsing');
|
q.addClass('collapsing');
|
||||||
q.css('overflow','hidden');
|
q.css('overflow','hidden');
|
||||||
q.find('.stream-item-expand').html(window.sL.expand);
|
q.find('.stream-item-expand').html(window.sL.expand);
|
||||||
|
@ -786,18 +845,19 @@ function expand_queet(q,doScrolling) {
|
||||||
q.find('.view-more-container-bottom').remove();
|
q.find('.view-more-container-bottom').remove();
|
||||||
q.find('.stream-item.conversation').remove();
|
q.find('.stream-item.conversation').remove();
|
||||||
q.find('.inline-reply-queetbox').remove();
|
q.find('.inline-reply-queetbox').remove();
|
||||||
q.find('.expanded-content').remove();
|
q.find('.expanded-content').remove();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rememberMyScrollPos(q.children('.queet'),qid,0);
|
rememberMyScrollPos(q.children('.queet'),qid,0);
|
||||||
|
|
||||||
// give stream item a height
|
// give stream item a height
|
||||||
q.css('height',q.height() + 'px');
|
q.css('height',q.height() + 'px');
|
||||||
|
q.children('.queet').find('.expanded-content').css('height',q.find('.expanded-content').height() + 'px');
|
||||||
|
|
||||||
q.children('div').not('.queet').children('a').css('opacity','0.5');
|
q.children('div').not('.queet').children('a').css('opacity','0.5');
|
||||||
q.children('div').not('.queet').children().children().css('opacity','0.5');
|
q.children('div').not('.queet').children().children().css('opacity','0.5');
|
||||||
|
|
||||||
var collapseTime = 150 + q.find('.stream-item.conversation:not(.hidden-conversation)').length*50;
|
var collapseTime = 350 + q.find('.stream-item.conversation:not(.hidden-conversation)').length*50;
|
||||||
|
|
||||||
// set transition time (needs to be delayed, otherwise webkit animates the height-setting above)
|
// set transition time (needs to be delayed, otherwise webkit animates the height-setting above)
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
@ -809,10 +869,15 @@ function expand_queet(q,doScrolling) {
|
||||||
q.css('-o-transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
q.css('-o-transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
||||||
q.css('-webkit-transition-duration',Math.round( collapseTime * 1000 * 10) / 10 + 's');
|
q.css('-webkit-transition-duration',Math.round( collapseTime * 1000 * 10) / 10 + 's');
|
||||||
q.css('transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
q.css('transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
||||||
|
q.find('.expanded-content').css('-moz-transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
||||||
|
q.find('.expanded-content').css('-o-transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
||||||
|
q.find('.expanded-content').css('-webkit-transition-duration',Math.round( collapseTime * 1000 * 10) / 10 + 's');
|
||||||
|
q.find('.expanded-content').css('transition-duration',Math.round( collapseTime / 1000 * 10) / 10 + 's');
|
||||||
|
|
||||||
// set new heights and margins to animate to
|
// set new heights and margins to animate to
|
||||||
q.css('height',(q.children('.queet').find('.queet-content').outerHeight() - q.children('.queet').find('.expanded-content').outerHeight() - 10) + 'px');
|
q.css('height',(q.children('.queet').find('.queet-content').outerHeight() - q.children('.queet').find('.expanded-content').outerHeight()) + 'px');
|
||||||
q.children('.queet').css('margin-top', '-' + (q.children('.queet').offset().top - q.offset().top) + 'px');
|
q.children('.queet').css('margin-top', '-' + (q.children('.queet').offset().top - q.offset().top) + 'px');
|
||||||
|
q.children('.queet').find('.expanded-content').css('height','0');
|
||||||
|
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
|
@ -839,12 +904,12 @@ function expand_queet(q,doScrolling) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if(!q.hasClass('collapsing')) {
|
||||||
|
|
||||||
rememberMyScrollPos(q,qid,-8);
|
rememberMyScrollPos(q,qid,-8);
|
||||||
|
|
||||||
// not for acitivity
|
// not for acitivity or notifications
|
||||||
if(!q.hasClass('activity')) {
|
if(!q.hasClass('activity') && !q.hasClass('repeat') && !q.hasClass('like') && !q.hasClass('follow')) {
|
||||||
|
|
||||||
q.addClass('expanded');
|
q.addClass('expanded');
|
||||||
q.find('.stream-item-expand').html(window.sL.collapse);
|
q.find('.stream-item-expand').html(window.sL.collapse);
|
||||||
|
@ -869,7 +934,7 @@ function expand_queet(q,doScrolling) {
|
||||||
var metadata = '<span class="longdate" title="' + longdate + '">' + longdate + ' · ' + unescape(q.attr('data-source')) + '</span> · <a href="' + qurl + '" class="permalink-link">' + window.sL.details + '</a>';
|
var metadata = '<span class="longdate" title="' + longdate + '">' + longdate + ' · ' + unescape(q.attr('data-source')) + '</span> · <a href="' + qurl + '" class="permalink-link">' + window.sL.details + '</a>';
|
||||||
|
|
||||||
// show expanded content
|
// show expanded content
|
||||||
q.find('.stream-item-footer').after('<div class="expanded-content"><div class="queet-stats-container"></div><div class="client-and-actions"><span class="metadata">' + metadata + '</span></div></div>');
|
q.find('.stream-item-footer').before('<div class="expanded-content"><div class="queet-stats-container"></div><div class="client-and-actions"><span class="metadata">' + metadata + '</span></div></div>');
|
||||||
|
|
||||||
|
|
||||||
// maybe show images or videos
|
// maybe show images or videos
|
||||||
|
@ -1327,13 +1392,68 @@ function checkForHiddenConversationQueets(qid) {
|
||||||
· · · · · · · · · · · · · */
|
· · · · · · · · · · · · · */
|
||||||
|
|
||||||
function addToFeed(feed, after, extraClasses) {
|
function addToFeed(feed, after, extraClasses) {
|
||||||
|
|
||||||
|
// some streams, e.g. /statuses/show/1234.json is not enclosed in an array, make sure it is
|
||||||
|
if(!$.isArray(feed)) {
|
||||||
|
feed = [feed];
|
||||||
|
}
|
||||||
|
|
||||||
$.each(feed.reverse(), function (key,obj) {
|
$.each(feed.reverse(), function (key,obj) {
|
||||||
|
|
||||||
var extraClassesThisRun = extraClasses;
|
var extraClassesThisRun = extraClasses;
|
||||||
|
|
||||||
|
// if this is the notifications feed
|
||||||
|
if(window.currentStream.substring(0,35) == 'qvitter/statuses/notifications.json') {
|
||||||
|
|
||||||
|
|
||||||
|
// only if this notification isn't already in stream
|
||||||
|
if($('#stream-item-' + obj.id).length == 0) {
|
||||||
|
|
||||||
|
obj.from_profile.description = obj.from_profile.description || '';
|
||||||
|
var notificationTime = parseTwitterDate(obj.created_at);
|
||||||
|
|
||||||
|
if(obj.is_seen == '0') {
|
||||||
|
extraClassesThisRun = extraClassesThisRun + ' not-seen'
|
||||||
|
}
|
||||||
|
|
||||||
|
if(obj.ntype == 'like') {
|
||||||
|
var noticeTime = parseTwitterDate(obj.notice.created_at);
|
||||||
|
obj.notice = convertNewGNUSocialURItoURL(obj.notice);
|
||||||
|
var notificationHtml = '<div data-quitter-id-in-stream="' + obj.id + '" id="stream-item-' + obj.id + '" class="stream-item ' + extraClassesThisRun + ' notification like"><div class="queet"><div class="queet-content"><div class="stream-item-header"><small class="created-at" data-created-at="' + obj.created_at + '" title="' + obj.created_at + '">' + notificationTime + '</small><a class="account-group" href="' + obj.from_profile.statusnet_profile_url + '"><span class="dogear"></span><img class="avatar" src="' + obj.from_profile.profile_image_url + '" /><strong class="name" data-user-id="' + obj.from_profile.id + '" title="@' + obj.from_profile.screen_name + '">' + obj.from_profile.name + '</strong></a> ' + window.sL.xFavedYourQueet + '</div><div class="small-grey-notice"><a href="' + obj.notice.uri + '">' + noticeTime + '</a>: ' + $.trim(obj.notice.statusnet_html) + '</div></div></div></div>';
|
||||||
|
}
|
||||||
|
else if(obj.ntype == 'repeat') {
|
||||||
|
obj.notice = convertNewGNUSocialURItoURL(obj.notice);
|
||||||
|
var noticeTime = parseTwitterDate(obj.notice.created_at);
|
||||||
|
var notificationHtml = '<div data-quitter-id-in-stream="' + obj.id + '" id="stream-item-' + obj.id + '" class="stream-item ' + extraClassesThisRun + ' notification repeat"><div class="queet"><div class="queet-content"><div class="stream-item-header"><small class="created-at" data-created-at="' + obj.created_at + '" title="' + obj.created_at + '">' + notificationTime + '</small><a class="account-group" href="' + obj.from_profile.statusnet_profile_url + '"><span class="dogear"></span><img class="avatar" src="' + obj.from_profile.profile_image_url + '" /><strong class="name" data-user-id="' + obj.from_profile.id + '" title="@' + obj.from_profile.screen_name + '">' + obj.from_profile.name + '</strong></a> ' + window.sL.xRepeatedYourQueet + '</div><div class="small-grey-notice"><a href="' + obj.notice.uri + '">' + noticeTime + '</a>: ' + $.trim(obj.notice.statusnet_html) + '</div></div></div></div>';
|
||||||
|
}
|
||||||
|
else if(obj.ntype == 'mention') {
|
||||||
|
var notificationHtml = buildQueetHtml(obj.notice, obj.id, extraClassesThisRun + ' notification mention');
|
||||||
|
}
|
||||||
|
else if(obj.ntype == 'reply') {
|
||||||
|
var notificationHtml = buildQueetHtml(obj.notice, obj.id, extraClassesThisRun + ' notification reply');
|
||||||
|
}
|
||||||
|
else if(obj.ntype == 'follow') {
|
||||||
|
var notificationHtml = '<div data-quitter-id-in-stream="' + obj.id + '" id="stream-item-' + obj.id + '" class="stream-item ' + extraClassesThisRun + ' notification follow"><div class="queet"><div class="queet-content"><div class="stream-item-header"><small class="created-at" data-created-at="' + obj.created_at + '" title="' + obj.created_at + '">' + notificationTime + '</small><a class="account-group" href="' + obj.from_profile.statusnet_profile_url + '"><img class="avatar" src="' + obj.from_profile.profile_image_url + '" /><strong class="name" data-user-id="' + obj.from_profile.id + '" title="@' + obj.from_profile.screen_name + '">' + obj.from_profile.name + '</strong></a> ' + window.sL.xStartedFollowingYou + '</div></div></div></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(after) {
|
||||||
|
$('#' + after).after(notificationHtml);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#feed-body').prepend(notificationHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add not seen notification circle
|
||||||
|
$.each($('.notification.not-seen .queet'),function(){
|
||||||
|
if($(this).children('.not-seen').length<1) {
|
||||||
|
$(this).prepend('<div class="not-seen"></div>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if this is a user feed
|
// if this is a user feed
|
||||||
if(window.currentStream.substring(0,21) == 'statuses/friends.json'
|
else if(window.currentStream.substring(0,21) == 'statuses/friends.json'
|
||||||
|| window.currentStream.substring(0,18) == 'statuses/followers'
|
|| window.currentStream.substring(0,18) == 'statuses/followers'
|
||||||
|| window.currentStream.substring(0,28) == 'statusnet/groups/membership/'
|
|| window.currentStream.substring(0,28) == 'statusnet/groups/membership/'
|
||||||
|| window.currentStream.substring(0,24) == 'statusnet/groups/admins/') {
|
|| window.currentStream.substring(0,24) == 'statusnet/groups/admins/') {
|
||||||
|
@ -1426,73 +1546,7 @@ function addToFeed(feed, after, extraClasses) {
|
||||||
// retweeted object don't exist in feed
|
// retweeted object don't exist in feed
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// we don't want to print 'null', someone might have that username!
|
var queetHtml = buildQueetHtml(obj.retweeted_status, obj.id, extraClassesThisRun, obj);
|
||||||
var in_reply_to_screen_name = '';
|
|
||||||
if(obj.retweeted_status.in_reply_to_screen_name != null) {
|
|
||||||
in_reply_to_screen_name = obj.retweeted_status.in_reply_to_screen_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// requeet html
|
|
||||||
var requeetedClass = '';
|
|
||||||
if(obj.retweeted_status.user.id == window.myUserID) {
|
|
||||||
var requeetHtml = '<li class="action-del-container"><a class="with-icn"><span class="icon sm-trash"></span> <b>' + window.sL.deleteVerb + '</b></a></li></i>';
|
|
||||||
}
|
|
||||||
else if(obj.retweeted_status.repeated) {
|
|
||||||
var requeetHtml = '<li class="action-rt-container"><a class="with-icn done"><span class="icon sm-rt"></span> <b>' + window.sL.requeetedVerb + '</b></a></i>';
|
|
||||||
requeetedClass = 'requeeted';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var requeetHtml = '<li class="action-rt-container"><a class="with-icn"><span class="icon sm-rt"></span> <b>' + window.sL.requeetVerb + '</b></a></i>';
|
|
||||||
}
|
|
||||||
// favorite html
|
|
||||||
var favoritedClass = '';
|
|
||||||
if(obj.retweeted_status.favorited) {
|
|
||||||
var favoriteHtml = '<a class="with-icn done"><span class="icon sm-fav"></span> <b>' + window.sL.favoritedVerb + '</b></a>';
|
|
||||||
favoritedClass = 'favorited';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var favoriteHtml = '<a class="with-icn"><span class="icon sm-fav"></span> <b>' + window.sL.favoriteVerb + '</b></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions only for logged in users
|
|
||||||
var queetActions = '';
|
|
||||||
if(typeof window.loggedIn.screen_name != 'undefined') {
|
|
||||||
queetActions = '<ul class="queet-actions"><li class="action-reply-container"><a class="with-icn"><span class="icon sm-reply"></span> <b>' + window.sL.replyVerb + '</b></a></li>' + requeetHtml + '<li class="action-fav-container">' + favoriteHtml + '</li></ul>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// reply-to html
|
|
||||||
var reply_to_html = '';
|
|
||||||
if(obj.retweeted_status.in_reply_to_screen_name != null && obj.retweeted_status.in_reply_to_screen_name != obj.retweeted_status.user.screen_name) {
|
|
||||||
reply_to_html = '<span class="reply-to">@' + obj.retweeted_status.in_reply_to_screen_name + '</span> ';
|
|
||||||
}
|
|
||||||
|
|
||||||
// in-groups html
|
|
||||||
var in_groups_html = '';
|
|
||||||
if(obj.retweeted_status.statusnet_in_groups !== false && typeof obj.retweeted_status.statusnet_in_groups != 'undefined') {
|
|
||||||
in_groups_html = '<span class="in-groups">' + obj.retweeted_status.statusnet_in_groups + '</span>';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// image attachment thumbnails
|
|
||||||
var attachment_html = '';
|
|
||||||
if(typeof obj.retweeted_status.attachments != "undefined") {
|
|
||||||
$.each(obj.retweeted_status.attachments, function(){
|
|
||||||
if(this.thumb_url != null) {
|
|
||||||
attachment_html = attachment_html + '<a href="' + this.url + '"><img src="' + this.thumb_url + '"/></a>';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(attachment_html.length>0) {
|
|
||||||
attachment_html = '<div class="attachments">' + attachment_html + '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.retweeted_status = convertNewGNUSocialURItoURL(obj.retweeted_status);
|
|
||||||
|
|
||||||
var queetTime = parseTwitterDate(obj.retweeted_status.created_at);
|
|
||||||
var queetHtml = '<div id="stream-item-' + obj.retweeted_status.id + '" class="stream-item ' + extraClassesThisRun + ' ' + requeetedClass + ' ' + favoritedClass + '" data-source="' + escape(obj.retweeted_status.source) + '" data-quitter-id="' + obj.retweeted_status.id + '" data-conversation-id="' + obj.retweeted_status.statusnet_conversation_id + '" data-quitter-id-in-stream="' + obj.id + '" data-in-reply-to-screen-name="' + in_reply_to_screen_name + '" data-in-reply-to-status-id="' + obj.retweeted_status.in_reply_to_status_id + '"><div class="queet" id="q-' + obj.retweeted_status.id + '">' + attachment_html + '<span class="dogear"></span><div class="queet-content"><div class="stream-item-header"><a class="account-group" href="' + obj.retweeted_status.user.statusnet_profile_url + '"><img class="avatar" src="' + obj.retweeted_status.user.profile_image_url_profile_size + '" /><strong class="name" data-user-id="' + obj.retweeted_status.user.id + '">' + obj.retweeted_status.user.name + '</strong> <span class="screen-name">@' + obj.retweeted_status.user.screen_name + '</span></a><i class="addressees">' + reply_to_html + in_groups_html + '</i><small class="created-at" data-created-at="' + obj.retweeted_status.created_at + '"><a href="' + obj.retweeted_status.uri + '">' + queetTime + '</a></small></div><div class="queet-text">' + $.trim(obj.retweeted_status.statusnet_html) + '</div><div class="stream-item-footer">' + queetActions + '<div class="context" id="requeet-' + obj.id + '"><span class="with-icn"><i class="badge-requeeted"></i><span class="requeet-text"> ' + window.sL.requeetedBy + '<a href="' + obj.user.statusnet_profile_url + '"> <b>' + obj.user.name + '</b></a></span></span></div><span class="stream-item-expand">' + window.sL.expand + '</span></div></div></div></div>';
|
|
||||||
|
|
||||||
// detect rtl
|
|
||||||
queetHtml = detectRTL(queetHtml);
|
|
||||||
|
|
||||||
if(after) {
|
if(after) {
|
||||||
$('#' + after).after(queetHtml);
|
$('#' + after).after(queetHtml);
|
||||||
|
@ -1549,74 +1603,7 @@ function addToFeed(feed, after, extraClasses) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't want to print 'null' in in_reply_to_screen_name-attribute, someone might have that username!
|
var queetHtml = buildQueetHtml(obj, obj.id, extraClassesThisRun);
|
||||||
var in_reply_to_screen_name = '';
|
|
||||||
if(obj.in_reply_to_screen_name != null) {
|
|
||||||
in_reply_to_screen_name = obj.in_reply_to_screen_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// requeet html
|
|
||||||
var requeetedClass = '';
|
|
||||||
if(obj.user.id == window.myUserID) {
|
|
||||||
var requeetHtml = '<li class="action-del-container"><a class="with-icn"><span class="icon sm-trash"></span> <b>' + window.sL.deleteVerb + '</b></a></li></i></li>';
|
|
||||||
}
|
|
||||||
else if(obj.repeated) {
|
|
||||||
var requeetHtml = '<li class="action-rt-container"><a class="with-icn done"><span class="icon sm-rt"></span> <b>' + window.sL.requeetedVerb + '</b></a></li>';
|
|
||||||
var requeetedClass = 'requeeted';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var requeetHtml = '<li class="action-rt-container"><a class="with-icn"><span class="icon sm-rt"></span> <b>' + window.sL.requeetVerb + '</b></a></li>';
|
|
||||||
}
|
|
||||||
// favorite html
|
|
||||||
var favoritedClass = '';
|
|
||||||
if(obj.favorited) {
|
|
||||||
var favoriteHtml = '<a class="with-icn done"><span class="icon sm-fav"></span> <b>' + window.sL.favoritedVerb + '</b></a>';
|
|
||||||
favoritedClass = 'favorited';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var favoriteHtml = '<a class="with-icn"><span class="icon sm-fav"></span> <b>' + window.sL.favoriteVerb + '</b></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// actions only for logged in users
|
|
||||||
var queetActions = '';
|
|
||||||
if(typeof window.loggedIn.screen_name != 'undefined') {
|
|
||||||
queetActions = '<ul class="queet-actions"><li class="action-reply-container"><a class="with-icn"><span class="icon sm-reply"></span> <b>' + window.sL.replyVerb + '</b></a></li>' + requeetHtml + '<li class="action-fav-container">' + favoriteHtml + '</li></ul>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// reply-to html
|
|
||||||
var reply_to_html = '';
|
|
||||||
if(obj.in_reply_to_screen_name != null && obj.in_reply_to_screen_name != obj.user.screen_name) {
|
|
||||||
reply_to_html = '<span class="reply-to">@' + obj.in_reply_to_screen_name + '</span> ';
|
|
||||||
}
|
|
||||||
|
|
||||||
// in-groups html
|
|
||||||
var in_groups_html = '';
|
|
||||||
if(obj.statusnet_in_groups !== false && typeof obj.statusnet_in_groups != 'undefined') {
|
|
||||||
in_groups_html = '<span class="in-groups">' + obj.statusnet_in_groups + '</span>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// image attachment thumbnails
|
|
||||||
var attachment_html = '';
|
|
||||||
if(typeof obj.attachments != "undefined") {
|
|
||||||
$.each(obj.attachments, function(){
|
|
||||||
if(this.thumb_url != null) {
|
|
||||||
attachment_html = attachment_html + '<a href="' + this.url + '"><img src="' + this.thumb_url + '"/></a>';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(attachment_html.length>0) {
|
|
||||||
attachment_html = '<div class="attachments">' + attachment_html + '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
obj = convertNewGNUSocialURItoURL(obj);
|
|
||||||
|
|
||||||
var queetTime = parseTwitterDate(obj.created_at);
|
|
||||||
var queetHtml = '<div id="stream-item-' + obj.id + '" class="stream-item ' + extraClassesThisRun + ' ' + requeetedClass + ' ' + favoritedClass + '" data-source="' + escape(obj.source) + '" data-quitter-id="' + obj.id + '" data-conversation-id="' + obj.statusnet_conversation_id + '" data-quitter-id-in-stream="' + obj.id + '" data-in-reply-to-screen-name="' + in_reply_to_screen_name + '" data-in-reply-to-status-id="' + obj.in_reply_to_status_id + '"><div class="queet" id="q-' + obj.id + '">' + attachment_html + '<span class="dogear"></span><div class="queet-content"><div class="stream-item-header"><a class="account-group" href="' + obj.user.statusnet_profile_url + '"><img class="avatar" src="' + obj.user.profile_image_url_profile_size + '" /><strong class="name" data-user-id="' + obj.user.id + '">' + obj.user.name + '</strong> <span class="screen-name">@' + obj.user.screen_name + '</span></a><i class="addressees">' + reply_to_html + in_groups_html + '</i><small class="created-at" data-created-at="' + obj.created_at + '"><a href="' + obj.uri + '">' + queetTime + '</a></small></div><div class="queet-text">' + $.trim(obj.statusnet_html) + '</div><div class="stream-item-footer">' + queetActions + '<span class="stream-item-expand">' + window.sL.expand + '</span></div></div></div></div>';
|
|
||||||
|
|
||||||
// detect rtl
|
|
||||||
queetHtml = detectRTL(queetHtml);
|
|
||||||
|
|
||||||
if(after) {
|
if(after) {
|
||||||
if($('#' + after).hasClass('conversation')) { // if this is a reply, give stream item some conversation formatting
|
if($('#' + after).hasClass('conversation')) { // if this is a reply, give stream item some conversation formatting
|
||||||
|
@ -1630,7 +1617,13 @@ function addToFeed(feed, after, extraClasses) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('#feed-body').prepend(queetHtml);
|
$('#feed-body').prepend(queetHtml);
|
||||||
|
|
||||||
|
// if this is a single notice, we expand it
|
||||||
|
if(window.currentStream.substring(0,14) == 'statuses/show/') {
|
||||||
|
expand_queet($('#stream-item-' + obj.id));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1642,61 +1635,125 @@ function addToFeed(feed, after, extraClasses) {
|
||||||
$('.stream-selection').removeAttr('data-current-user-stream-name'); // don't remeber user feeds
|
$('.stream-selection').removeAttr('data-current-user-stream-name'); // don't remeber user feeds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ·
|
/* ·
|
||||||
·
|
·
|
||||||
· View threaded converation
|
· Build HTML for a queet from an object
|
||||||
·
|
·
|
||||||
· @param id: the stream item id
|
· @param obj: a queet object
|
||||||
·
|
· @param requeeted_by: if this is a requeet
|
||||||
· (experimental, not finished, commented out...)
|
|
||||||
·
|
·
|
||||||
· · · · · · · · · · · · · */
|
· · · · · · · · · · · · · */
|
||||||
|
|
||||||
// $('body').on('click','.longdate',function(){
|
function buildQueetHtml(obj, idInStream, extraClassesThisRun, requeeted_by) {
|
||||||
// threadedConversation($(this).closest('.stream-item:not(.conversation)').attr('data-quitter-id'));
|
|
||||||
// })
|
// we don't want to print 'null' in in_reply_to_screen_name-attribute, someone might have that username!
|
||||||
// function threadedConversation(id){
|
var in_reply_to_screen_name = '';
|
||||||
// $('body').prepend('<div id="threaded-' + id + '" class="modal-container"><div class="thread-container" style="margin-left:0;"><div></div></div></div>');
|
if(obj.in_reply_to_screen_name != null) {
|
||||||
// var scrollTop = $(window).scrollTop();
|
in_reply_to_screen_name = obj.in_reply_to_screen_name;
|
||||||
// var containerStreamItem = $('#stream-item-' + id);
|
}
|
||||||
// if(containerStreamItem.children('div:first-child').hasClass('.queet')) {
|
|
||||||
// var firstStreamItemId = id;
|
// requeet html
|
||||||
// }
|
var requeetedClass = '';
|
||||||
// else {
|
if(obj.user.id == window.myUserID) {
|
||||||
// var firstStreamItemId = containerStreamItem.children('div:first-child').attr('data-quitter-id');
|
var requeetHtml = '<li class="action-del-container"><a class="with-icn"><span class="icon sm-trash"></span> <b>' + window.sL.deleteVerb + '</b></a></li></i></li>';
|
||||||
// }
|
}
|
||||||
// getThreadedReply(id,firstStreamItemId,$('#threaded-' + id + ' .thread-container div'));
|
else if(obj.repeated) {
|
||||||
// }
|
var requeetHtml = '<li class="action-rt-container"><a class="with-icn done"><span class="icon sm-rt"></span> <b>' + window.sL.requeetedVerb + '</b></a></li>';
|
||||||
//
|
var requeetedClass = 'requeeted';
|
||||||
// function getThreadedReply(containerStreamId,this_id,appendToObj) {
|
}
|
||||||
//
|
else {
|
||||||
// var $this_item = $('<div/>').append($('.stream-item[data-quitter-id="' + this_id + '"]').outerHTML());
|
var requeetHtml = '<li class="action-rt-container"><a class="with-icn"><span class="icon sm-rt"></span> <b>' + window.sL.requeetVerb + '</b></a></li>';
|
||||||
// $this_item.children().children().remove('.stream-item.conversation');
|
}
|
||||||
// $this_item.children('.stream-item').css('margin-left',parseInt(appendToObj.css('margin-left'),10)+20 + 'px');
|
// favorite html
|
||||||
// $this_item.children('.stream-item').removeClass('hidden-conversation');
|
var favoritedClass = '';
|
||||||
// $this_item.children('.stream-item').removeClass('expanded');
|
if(obj.favorited) {
|
||||||
// $this_item.children('.stream-item').removeClass('activity');
|
var favoriteHtml = '<a class="with-icn done"><span class="icon sm-fav"></span> <b>' + window.sL.favoritedVerb + '</b></a>';
|
||||||
// $this_item.children('.stream-item').removeClass('conversation');
|
favoritedClass = 'favorited';
|
||||||
// $this_item.children('.stream-item').removeClass('visible');
|
}
|
||||||
// $this_item.children('.stream-item').children('div:not(.queet)').remove();
|
else {
|
||||||
// $this_item.children('.stream-item').find('.inline-reply-queetbox').remove();
|
var favoriteHtml = '<a class="with-icn"><span class="icon sm-fav"></span> <b>' + window.sL.favoriteVerb + '</b></a>';
|
||||||
// $this_item.children('.stream-item').find('.expanded-content').remove();
|
}
|
||||||
// $this_item.children('.stream-item').find('.stream-item-expand').remove();
|
|
||||||
// $this_item.children('.stream-item').css('opacity','1');
|
|
||||||
// appendToObj.after($this_item.html());
|
// actions only for logged in users
|
||||||
//
|
var queetActions = '';
|
||||||
// $.each($('.stream-item[data-quitter-id="' + containerStreamId + '"]').children().get().reverse(),function(){
|
if(typeof window.loggedIn.screen_name != 'undefined') {
|
||||||
// if($(this).hasClass('queet')) {
|
queetActions = '<ul class="queet-actions"><li class="action-reply-container"><a class="with-icn"><span class="icon sm-reply"></span> <b>' + window.sL.replyVerb + '</b></a></li>' + requeetHtml + '<li class="action-fav-container">' + favoriteHtml + '</li></ul>';
|
||||||
// var this_reply_to = $(this).parent().attr('data-in-reply-to-status-id');
|
}
|
||||||
// var childs_id = $(this).parent().attr('data-quitter-id');
|
|
||||||
// }
|
// reply-to html
|
||||||
// else {
|
var reply_to_html = '';
|
||||||
// var this_reply_to = $(this).attr('data-in-reply-to-status-id');
|
if(obj.in_reply_to_screen_name != null && obj.in_reply_to_screen_name != obj.user.screen_name) {
|
||||||
// var childs_id = $(this).attr('data-quitter-id');
|
reply_to_html = '<span class="reply-to">@' + obj.in_reply_to_screen_name + '</span> ';
|
||||||
// }
|
}
|
||||||
// if(this_id == this_reply_to) {
|
|
||||||
// getThreadedReply(containerStreamId,childs_id,$('#threaded-' + containerStreamId + ' .stream-item[data-quitter-id="' + this_id + '"]'));
|
// in-groups html
|
||||||
// }
|
var in_groups_html = '';
|
||||||
// });
|
if(obj.statusnet_in_groups !== false && typeof obj.statusnet_in_groups != 'undefined') {
|
||||||
// }
|
in_groups_html = '<span class="in-groups">' + obj.statusnet_in_groups + '</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// image attachment thumbnails
|
||||||
|
var attachment_html = '';
|
||||||
|
if(typeof obj.attachments != "undefined") {
|
||||||
|
$.each(obj.attachments, function(){
|
||||||
|
if(this.thumb_url != null) {
|
||||||
|
attachment_html = attachment_html + '<a href="' + this.url + '"><img src="' + this.thumb_url + '"/></a>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(attachment_html.length>0) {
|
||||||
|
attachment_html = '<div class="attachments">' + attachment_html + '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// requeets
|
||||||
|
var requeetHtml = '';
|
||||||
|
if(typeof requeeted_by != 'undefined') {
|
||||||
|
requeetHtml = '<div class="context" id="requeet-' + requeeted_by.id + '"><span class="with-icn"><i class="badge-requeeted"></i><span class="requeet-text"> ' + window.sL.requeetedBy + '<a href="' + requeeted_by.user.statusnet_profile_url + '"> <b>' + requeeted_by.user.name + '</b></a></span></span></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
obj = convertNewGNUSocialURItoURL(obj);
|
||||||
|
|
||||||
|
var queetTime = parseTwitterDate(obj.created_at);
|
||||||
|
var queetHtml = '<div \
|
||||||
|
id="stream-item-' + obj.id + '" \
|
||||||
|
class="stream-item ' + extraClassesThisRun + ' ' + requeetedClass + ' ' + favoritedClass + '" \
|
||||||
|
data-source="' + escape(obj.source) + '" \
|
||||||
|
data-quitter-id="' + obj.id + '" \
|
||||||
|
data-conversation-id="' + obj.statusnet_conversation_id + '" \
|
||||||
|
data-quitter-id-in-stream="' + idInStream + '" \
|
||||||
|
data-in-reply-to-screen-name="' + in_reply_to_screen_name + '" \
|
||||||
|
data-in-reply-to-status-id="' + obj.in_reply_to_status_id + '">\
|
||||||
|
<div class="queet" id="q-' + obj.id + '">\
|
||||||
|
' + attachment_html + '\
|
||||||
|
<span class="dogear"></span>\
|
||||||
|
<div class="queet-content">\
|
||||||
|
<div class="stream-item-header">\
|
||||||
|
<a class="account-group" href="' + obj.user.statusnet_profile_url + '">\
|
||||||
|
<img class="avatar" src="' + obj.user.profile_image_url_profile_size + '" />\
|
||||||
|
<strong class="name" data-user-id="' + obj.user.id + '">' + obj.user.name + '</strong> \
|
||||||
|
<span class="screen-name">@' + obj.user.screen_name + '</span>\
|
||||||
|
</a>\
|
||||||
|
<i class="addressees">' + reply_to_html + in_groups_html + '</i>\
|
||||||
|
<small class="created-at" data-created-at="' + obj.created_at + '">\
|
||||||
|
<a href="' + obj.uri + '">' + queetTime + '</a>\
|
||||||
|
</small>\
|
||||||
|
</div>\
|
||||||
|
<div class="queet-text">' + $.trim(obj.statusnet_html) + '</div>\
|
||||||
|
<div class="stream-item-footer">\
|
||||||
|
' + queetActions + '\
|
||||||
|
' + requeetHtml + '\
|
||||||
|
<span class="stream-item-expand">' + window.sL.expand + '</span>\
|
||||||
|
</div>\
|
||||||
|
</div>\
|
||||||
|
</div>\
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// detect rtl
|
||||||
|
queetHtml = detectRTL(queetHtml);
|
||||||
|
|
||||||
|
return queetHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
75
js/lan.js
75
js/lan.js
|
@ -146,6 +146,11 @@ window.l.es.registerRepeatPassword = 'Verificar contraseña';
|
||||||
window.l.es.moreSettings = 'Más configuraciones';
|
window.l.es.moreSettings = 'Más configuraciones';
|
||||||
window.l.es.otherServers = 'De manera alternativa, puedes crear una cuenta en otro servidor de la red GNUsocial. <a href="http://federation.skilledtests.com/select_your_server.html">Comparativa</a>';
|
window.l.es.otherServers = 'De manera alternativa, puedes crear una cuenta en otro servidor de la red GNUsocial. <a href="http://federation.skilledtests.com/select_your_server.html">Comparativa</a>';
|
||||||
window.l.es.editMyProfile = 'Editar perfil';
|
window.l.es.editMyProfile = 'Editar perfil';
|
||||||
|
window.l.es.notifications = 'Notificaciones';
|
||||||
|
window.l.es.xFavedYourQueet = 'marcó tu Queet como favorito';
|
||||||
|
window.l.es.xRepeatedYourQueet = 'te ha requitteado ';
|
||||||
|
window.l.es.xStartedFollowingYou = 'te ha seguido';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Português-Brasil
|
// Português-Brasil
|
||||||
|
@ -257,6 +262,13 @@ window.l.pt_br.registerRepeatPassword = 'Repetir senha';
|
||||||
window.l.pt_br.moreSettings = 'Mais configurações';
|
window.l.pt_br.moreSettings = 'Mais configurações';
|
||||||
window.l.pt_br.otherServers = 'De manera alternativa, você pode criar uma conta em outro servidor da rede GNUsocial. <a href="http://federation.skilledtests.com/select_your_server.html">Comparativo</a>';
|
window.l.pt_br.otherServers = 'De manera alternativa, você pode criar uma conta em outro servidor da rede GNUsocial. <a href="http://federation.skilledtests.com/select_your_server.html">Comparativo</a>';
|
||||||
window.l.pt_br.editMyProfile = 'Editar perfil';
|
window.l.pt_br.editMyProfile = 'Editar perfil';
|
||||||
|
window.l.pt_br.notifications = 'Notificações';
|
||||||
|
window.l.pt_br.xFavedYourQueet = 'curtiu seu Queet';
|
||||||
|
window.l.pt_br.xRepeatedYourQueet = 'requeetou você';
|
||||||
|
window.l.pt_br.xStartedFollowingYou = 'seguiu você';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// galician
|
// galician
|
||||||
window.l.gl = new Object();
|
window.l.gl = new Object();
|
||||||
|
@ -367,6 +379,10 @@ window.l.gl.registerRepeatPassword = 'Verificar contrasinal';
|
||||||
window.l.gl.moreSettings = 'máis opcións';
|
window.l.gl.moreSettings = 'máis opcións';
|
||||||
window.l.gl.otherServers = 'De maneira alternativa, podes crear unha conta noutro servidor da rede GNUsocial. <a href="http://federation.skilledtests.com/select_your_server.html">Comparativa</a>';
|
window.l.gl.otherServers = 'De maneira alternativa, podes crear unha conta noutro servidor da rede GNUsocial. <a href="http://federation.skilledtests.com/select_your_server.html">Comparativa</a>';
|
||||||
window.l.gl.editMyProfile = 'Editar o perfil';
|
window.l.gl.editMyProfile = 'Editar o perfil';
|
||||||
|
window.l.gl.notifications = 'Notificacións';
|
||||||
|
window.l.gl.xFavedYourQueet = 'marcou como favorito o teu chío';
|
||||||
|
window.l.gl.xRepeatedYourQueet = 'rechouchioute';
|
||||||
|
window.l.gl.xStartedFollowingYou = 'está a seguirte';
|
||||||
|
|
||||||
|
|
||||||
// basque
|
// basque
|
||||||
|
@ -478,6 +494,11 @@ window.l.eu.registerRepeatPassword = 'Errepikatu pasahitza';
|
||||||
window.l.eu.moreSettings = 'Aukera gehiago';
|
window.l.eu.moreSettings = 'Aukera gehiago';
|
||||||
window.l.eu.otherServers = 'GNU social sareko beste nodo batean sor dezakezu kontu bat nahi izanez gero. <a href="http://federation.skilledtests.com/select_your_server.html">Alderatu</a>';
|
window.l.eu.otherServers = 'GNU social sareko beste nodo batean sor dezakezu kontu bat nahi izanez gero. <a href="http://federation.skilledtests.com/select_your_server.html">Alderatu</a>';
|
||||||
window.l.eu.editMyProfile = 'Editatu profila';
|
window.l.eu.editMyProfile = 'Editatu profila';
|
||||||
|
window.l.eu.notifications = 'Jakinarazpenak';
|
||||||
|
window.l.eu.xFavedYourQueet = 'erabiltzaileak gustuko du zure Txioa';
|
||||||
|
window.l.eu.xRepeatedYourQueet = 'erabiltzaileak bertxiotu zaitu';
|
||||||
|
window.l.eu.xStartedFollowingYou = 'jarraitzen hasi zaizu';
|
||||||
|
|
||||||
|
|
||||||
// french
|
// french
|
||||||
window.l.fr = new Object();
|
window.l.fr = new Object();
|
||||||
|
@ -588,6 +609,10 @@ window.l.fr.registerRepeatPassword = 'Vérifiez votre mot de passe';
|
||||||
window.l.fr.moreSettings = 'Plus de paramètres';
|
window.l.fr.moreSettings = 'Plus de paramètres';
|
||||||
window.l.fr.otherServers = '';
|
window.l.fr.otherServers = '';
|
||||||
window.l.fr.editMyProfile = 'Éditer le profil';
|
window.l.fr.editMyProfile = 'Éditer le profil';
|
||||||
|
window.l.fr.notifications = 'Notifications';
|
||||||
|
window.l.fr.xFavedYourQueet = 'a ajouté votre Queet à ses favoris ';
|
||||||
|
window.l.fr.xRepeatedYourQueet = 'vous a requeeté ';
|
||||||
|
window.l.fr.xStartedFollowingYou = 'vous a suivi';
|
||||||
|
|
||||||
|
|
||||||
// deutsch
|
// deutsch
|
||||||
|
@ -711,6 +736,10 @@ window.l.de.registerRepeatPassword = 'Passwort bestätigen';
|
||||||
window.l.de.moreSettings = 'Weitere Einstellungen';
|
window.l.de.moreSettings = 'Weitere Einstellungen';
|
||||||
window.l.de.otherServers = 'Du kannst Dir auch gerne ein Konto auf einem anderen Server des GNUsocial-Netzwerks einrichten. <a href="http://federation.skilledtests.com/select_your_server.html">Übersicht</a>';
|
window.l.de.otherServers = 'Du kannst Dir auch gerne ein Konto auf einem anderen Server des GNUsocial-Netzwerks einrichten. <a href="http://federation.skilledtests.com/select_your_server.html">Übersicht</a>';
|
||||||
window.l.de.editMyProfile = 'Profil bearbeiten';
|
window.l.de.editMyProfile = 'Profil bearbeiten';
|
||||||
|
window.l.de.notifications = 'Mitteilungen';
|
||||||
|
window.l.de.xFavedYourQueet = 'favorisierte Deinen Queet';
|
||||||
|
window.l.de.xRepeatedYourQueet = 'hat Dich requeetet';
|
||||||
|
window.l.de.xStartedFollowingYou = 'folgt Dir jetzt';
|
||||||
|
|
||||||
|
|
||||||
// english
|
// english
|
||||||
|
@ -830,6 +859,12 @@ window.l.en.registerRepeatPassword = 'Repeat password';
|
||||||
window.l.en.moreSettings = 'More settings';
|
window.l.en.moreSettings = 'More settings';
|
||||||
window.l.en.otherServers = 'Alternatively you can create an account on another server of the GNU social network. <a href="http://federation.skilledtests.com/select_your_server.html">Comparison</a>';
|
window.l.en.otherServers = 'Alternatively you can create an account on another server of the GNU social network. <a href="http://federation.skilledtests.com/select_your_server.html">Comparison</a>';
|
||||||
window.l.en.editMyProfile = 'Edit profile';
|
window.l.en.editMyProfile = 'Edit profile';
|
||||||
|
window.l.en.notifications = 'Notifications';
|
||||||
|
window.l.en.xFavedYourQueet = 'favorited your Queet';
|
||||||
|
window.l.en.xRepeatedYourQueet = 'requeeted you';
|
||||||
|
window.l.en.xStartedFollowingYou = 'followed you';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// simplified chinese
|
// simplified chinese
|
||||||
window.l.zh_cn = new Object();
|
window.l.zh_cn = new Object();
|
||||||
|
@ -940,6 +975,12 @@ window.l.zh_cn.registerRepeatPassword = '重复密码';
|
||||||
window.l.zh_cn.moreSettings = '更多的设置';
|
window.l.zh_cn.moreSettings = '更多的设置';
|
||||||
window.l.zh_cn.otherServers = '其他服务器: <a href="http://federation.skilledtests.com/select_your_server.html">对照</a>';
|
window.l.zh_cn.otherServers = '其他服务器: <a href="http://federation.skilledtests.com/select_your_server.html">对照</a>';
|
||||||
window.l.zh_cn.editMyProfile = '编辑个人资料';
|
window.l.zh_cn.editMyProfile = '编辑个人资料';
|
||||||
|
window.l.zh_cn.notifications = '通知';
|
||||||
|
window.l.zh_cn.xFavedYourQueet = '收藏了你的推文';
|
||||||
|
window.l.zh_cn.xRepeatedYourQueet = '转推了你的推文';
|
||||||
|
window.l.zh_cn.xStartedFollowingYou = '关注了你';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// traditional chinese
|
// traditional chinese
|
||||||
window.l.zh_tw = new Object();
|
window.l.zh_tw = new Object();
|
||||||
|
@ -1050,6 +1091,12 @@ window.l.zh_tw.registerRepeatPassword = '重複密碼';
|
||||||
window.l.zh_tw.moreSettings = '更多的設置';
|
window.l.zh_tw.moreSettings = '更多的設置';
|
||||||
window.l.zh_tw.otherServers = '其他服務器: <a href="http://federation.skilledtests.com/select_your_server.html">對照</a>';
|
window.l.zh_tw.otherServers = '其他服務器: <a href="http://federation.skilledtests.com/select_your_server.html">對照</a>';
|
||||||
window.l.zh_tw.editMyProfile = '編輯個人檔案';
|
window.l.zh_tw.editMyProfile = '編輯個人檔案';
|
||||||
|
window.l.zh_tw.notifications = '通知';
|
||||||
|
window.l.zh_tw.xFavedYourQueet = '已收藏你的推文';
|
||||||
|
window.l.zh_tw.xRepeatedYourQueet = '已轉推你';
|
||||||
|
window.l.zh_tw.xStartedFollowingYou = '已跟隨你';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// svenska
|
// svenska
|
||||||
window.l.sv = new Object();
|
window.l.sv = new Object();
|
||||||
|
@ -1160,7 +1207,10 @@ window.l.sv.registerRepeatPassword = 'Upprepa lösenord';
|
||||||
window.l.sv.moreSettings = 'Fler inställningar';
|
window.l.sv.moreSettings = 'Fler inställningar';
|
||||||
window.l.sv.otherServers = 'Men du kan lika gärna skapa ett konto på en annan server som är del av GNU social-nätverket. <a href="http://federation.skilledtests.com/select_your_server.html">Här är en jämförelse.</a>';
|
window.l.sv.otherServers = 'Men du kan lika gärna skapa ett konto på en annan server som är del av GNU social-nätverket. <a href="http://federation.skilledtests.com/select_your_server.html">Här är en jämförelse.</a>';
|
||||||
window.l.sv.editMyProfile = 'Redigera profil';
|
window.l.sv.editMyProfile = 'Redigera profil';
|
||||||
|
window.l.sv.notifications = 'Notiser';
|
||||||
|
window.l.sv.xFavedYourQueet = 'favoritmarkerade ditt qvitter';
|
||||||
|
window.l.sv.xRepeatedYourQueet = 'requeetade dig';
|
||||||
|
window.l.sv.xStartedFollowingYou = 'följde dig';
|
||||||
|
|
||||||
// farsi/persian
|
// farsi/persian
|
||||||
window.l.fa = new Object();
|
window.l.fa = new Object();
|
||||||
|
@ -1271,6 +1321,10 @@ window.l.fa.registerRepeatPassword = 'تایید گذرواژه';
|
||||||
window.l.fa.moreSettings = 'تنظیمات بیشتر';
|
window.l.fa.moreSettings = 'تنظیمات بیشتر';
|
||||||
window.l.fa.otherServers = '';
|
window.l.fa.otherServers = '';
|
||||||
window.l.fa.editMyProfile = 'ویرایش نمایه';
|
window.l.fa.editMyProfile = 'ویرایش نمایه';
|
||||||
|
window.l.fa.notifications = 'آگاهسازیها';
|
||||||
|
window.l.fa.xFavedYourQueet = 'موارد دلخواه خود را صدای جیر جیر';
|
||||||
|
window.l.fa.xRepeatedYourQueet = 'توییت شما را باز توییت کرد.';
|
||||||
|
window.l.fa.xStartedFollowingYou = 'شما را دنبال کرد';
|
||||||
|
|
||||||
// arabic
|
// arabic
|
||||||
window.l.ar = new Object();
|
window.l.ar = new Object();
|
||||||
|
@ -1381,6 +1435,10 @@ window.l.ar.registerRepeatPassword = 'تأكيد كلمة المرور';
|
||||||
window.l.ar.moreSettings = 'مزيد من الإعدادات';
|
window.l.ar.moreSettings = 'مزيد من الإعدادات';
|
||||||
window.l.ar.otherServers = '';
|
window.l.ar.otherServers = '';
|
||||||
window.l.ar.editMyProfile = 'تعديل الملف الشخصي';
|
window.l.ar.editMyProfile = 'تعديل الملف الشخصي';
|
||||||
|
window.l.ar.notifications = 'التنبيهات';
|
||||||
|
window.l.ar.xFavedYourQueet = 'بتفضيل تغريدتك';
|
||||||
|
window.l.ar.xRepeatedYourQueet = 'بإعادة تغريد';
|
||||||
|
window.l.ar.xStartedFollowingYou = 'بمتابعتك';
|
||||||
|
|
||||||
// esperanto
|
// esperanto
|
||||||
window.l.eo = new Object();
|
window.l.eo = new Object();
|
||||||
|
@ -1500,7 +1558,10 @@ window.l.eo.registerRepeatPassword = 'Ripeti pasvorton';
|
||||||
window.l.eo.moreSettings = 'Pli agordoj';
|
window.l.eo.moreSettings = 'Pli agordoj';
|
||||||
window.l.eo.otherServers = '';
|
window.l.eo.otherServers = '';
|
||||||
window.l.eo.editMyProfile = 'Redaktu profilon';
|
window.l.eo.editMyProfile = 'Redaktu profilon';
|
||||||
|
window.l.eo.notifications = 'Sciigoj';
|
||||||
|
window.l.eo.xFavedYourQueet = 'ŝatataj via avizo';
|
||||||
|
window.l.eo.xRepeatedYourQueet = 'ripetis vin';
|
||||||
|
window.l.eo.xStartedFollowingYou = 'sekvas vin';
|
||||||
|
|
||||||
// italian
|
// italian
|
||||||
window.l.it = new Object();
|
window.l.it = new Object();
|
||||||
|
@ -1620,6 +1681,10 @@ window.l.it.registerRepeatPassword = 'Ripetere la password';
|
||||||
window.l.it.moreSettings = 'Altre opzioni';
|
window.l.it.moreSettings = 'Altre opzioni';
|
||||||
window.l.it.otherServers = 'In alternativa puoi creare un account su un altro server della rete GNU Social. <a href="http://federation.skilledtests.com/select_your_server.html">Confronto</a>';
|
window.l.it.otherServers = 'In alternativa puoi creare un account su un altro server della rete GNU Social. <a href="http://federation.skilledtests.com/select_your_server.html">Confronto</a>';
|
||||||
window.l.it.editMyProfile = 'Modifica profilo';
|
window.l.it.editMyProfile = 'Modifica profilo';
|
||||||
|
window.l.it.notifications = 'Notifiche';
|
||||||
|
window.l.it.xFavedYourQueet = 'ha aggiunto ai preferiti il tuo Queet';
|
||||||
|
window.l.it.xRepeatedYourQueet = 'ti ha requittato';
|
||||||
|
window.l.it.xStartedFollowingYou = 'ha iniziato a seguirti';
|
||||||
|
|
||||||
// Norwegian
|
// Norwegian
|
||||||
window.l.no = new Object();
|
window.l.no = new Object();
|
||||||
|
@ -1730,6 +1795,10 @@ window.l.no.registerRepeatPassword = 'Gjenta passord';
|
||||||
window.l.no.moreSettings = 'Flere instillinger';
|
window.l.no.moreSettings = 'Flere instillinger';
|
||||||
window.l.no.otherServers = 'Det finnes flere instanser i GNUsocial nettverket som alternativt kan benyttes. <a href="http://gnu.io/social/try/">Følger du denne lenken finner du noen anbefalinger.</a>';
|
window.l.no.otherServers = 'Det finnes flere instanser i GNUsocial nettverket som alternativt kan benyttes. <a href="http://gnu.io/social/try/">Følger du denne lenken finner du noen anbefalinger.</a>';
|
||||||
window.l.no.editMyProfile = 'Rediger profil';
|
window.l.no.editMyProfile = 'Rediger profil';
|
||||||
|
window.l.no.notifications = 'Varsler';
|
||||||
|
window.l.no.xFavedYourQueet = 'favorittmarkerte queeten din';
|
||||||
|
window.l.no.xRepeatedYourQueet = 'requeetet deg';
|
||||||
|
window.l.no.xStartedFollowingYou = 'følger deg';
|
||||||
|
|
||||||
|
|
||||||
// set language, from local storage, else browser language, else english (english also if no localstorage availible)
|
// set language, from local storage, else browser language, else english (english also if no localstorage availible)
|
||||||
|
@ -1797,6 +1866,8 @@ $('.stream-selection[data-stream-name="qvitter/statuses/friends_timeline.json"]'
|
||||||
$('.stream-selection[data-stream-name="qvitter/statuses/friends_timeline.json"]').attr('data-stream-header',window.sL.timeline);
|
$('.stream-selection[data-stream-name="qvitter/statuses/friends_timeline.json"]').attr('data-stream-header',window.sL.timeline);
|
||||||
$('.stream-selection[data-stream-name="qvitter/statuses/mentions.json"]').prepend(window.sL.mentions);
|
$('.stream-selection[data-stream-name="qvitter/statuses/mentions.json"]').prepend(window.sL.mentions);
|
||||||
$('.stream-selection[data-stream-name="qvitter/statuses/mentions.json"]').attr('data-stream-header',window.sL.mentions);
|
$('.stream-selection[data-stream-name="qvitter/statuses/mentions.json"]').attr('data-stream-header',window.sL.mentions);
|
||||||
|
$('.stream-selection[data-stream-name="qvitter/statuses/notifications.json"]').prepend(window.sL.notifications);
|
||||||
|
$('.stream-selection[data-stream-name="qvitter/statuses/notifications.json"]').attr('data-stream-header',window.sL.notifications);
|
||||||
$('.stream-selection[data-stream-name="favorites.json"]').prepend(window.sL.favoritesNoun);
|
$('.stream-selection[data-stream-name="favorites.json"]').prepend(window.sL.favoritesNoun);
|
||||||
$('.stream-selection[data-stream-name="favorites.json"]').attr('data-stream-header',window.sL.favoritesNoun);
|
$('.stream-selection[data-stream-name="favorites.json"]').attr('data-stream-header',window.sL.favoritesNoun);
|
||||||
$('.stream-selection[data-stream-name="statuses/public_timeline.json"]').prepend(window.sL.publicTimeline);
|
$('.stream-selection[data-stream-name="statuses/public_timeline.json"]').prepend(window.sL.publicTimeline);
|
||||||
|
|
6
js/lib/jquery-2.0.2.min.js
vendored
6
js/lib/jquery-2.0.2.min.js
vendored
File diff suppressed because one or more lines are too long
4
js/lib/jquery-2.1.1.min.js
vendored
Normal file
4
js/lib/jquery-2.1.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -458,25 +458,27 @@ function findUrls(text) {
|
||||||
· · · · · · · · · · · · */
|
· · · · · · · · · · · · */
|
||||||
|
|
||||||
function display_spinner() {
|
function display_spinner() {
|
||||||
$('body').prepend('\
|
if($('.loader').length<1) {
|
||||||
<div class="loader">\
|
$('body').prepend('\
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\
|
<div class="loader">\
|
||||||
width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">\
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\
|
||||||
<path opacity="0.2" enable-background="new " d="M20.201,8.503c-6.413,0-11.612,5.199-11.612,11.612s5.199,11.611,11.612,11.611\
|
width="40px" height="40px" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">\
|
||||||
c6.412,0,11.611-5.198,11.611-11.611S26.613,8.503,20.201,8.503z M20.201,29.153c-4.992,0-9.039-4.046-9.039-9.038\
|
<path opacity="0.2" enable-background="new " d="M20.201,8.503c-6.413,0-11.612,5.199-11.612,11.612s5.199,11.611,11.612,11.611\
|
||||||
s4.047-9.039,9.039-9.039c4.991,0,9.038,4.047,9.038,9.039S25.192,29.153,20.201,29.153z"/>\
|
c6.412,0,11.611-5.198,11.611-11.611S26.613,8.503,20.201,8.503z M20.201,29.153c-4.992,0-9.039-4.046-9.039-9.038\
|
||||||
<path d="M24.717,12.293l1.285-2.227c-1.708-0.988-3.686-1.563-5.801-1.563l0,0v2.573l0,0C21.848,11.076,23.386,11.524,24.717,12.293 z">\
|
s4.047-9.039,9.039-9.039c4.991,0,9.038,4.047,9.038,9.039S25.192,29.153,20.201,29.153z"/>\
|
||||||
<animateTransform attributeType="xml"\
|
<path d="M24.717,12.293l1.285-2.227c-1.708-0.988-3.686-1.563-5.801-1.563l0,0v2.573l0,0C21.848,11.076,23.386,11.524,24.717,12.293 z">\
|
||||||
attributeName="transform"\
|
<animateTransform attributeType="xml"\
|
||||||
type="rotate"\
|
attributeName="transform"\
|
||||||
from="0 20 20"\
|
type="rotate"\
|
||||||
to="360 20 20"\
|
from="0 20 20"\
|
||||||
dur="1s"\
|
to="360 20 20"\
|
||||||
repeatCount="indefinite"/>\
|
dur="1s"\
|
||||||
</path>\
|
repeatCount="indefinite"/>\
|
||||||
</svg>\
|
</path>\
|
||||||
</div>\
|
</svg>\
|
||||||
');
|
</div>\
|
||||||
|
');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function remove_spinner() {
|
function remove_spinner() {
|
||||||
$('.loader').remove();
|
$('.loader').remove();
|
||||||
|
|
|
@ -59,12 +59,12 @@ window.onpopstate = function(event) {
|
||||||
·
|
·
|
||||||
· · · · · · · · · · · · · */
|
· · · · · · · · · · · · · */
|
||||||
|
|
||||||
window.loginContentStartPos = $('.front-welcome-text').height()+45;
|
|
||||||
$(window).scroll(function(e){
|
$(window).scroll(function(e){
|
||||||
if ($(this).scrollTop() > window.loginContentStartPos && $('#login-content').css('position') != 'fixed'){
|
// console.log($('#feed').offset().top);
|
||||||
|
if ($(this).scrollTop() > ($('#feed').offset().top-50) && $('#login-content').css('position') != 'fixed'){
|
||||||
$('#login-content, .front-signup').not('#popup-signup').css({'position': 'fixed', 'top': '50px'});
|
$('#login-content, .front-signup').not('#popup-signup').css({'position': 'fixed', 'top': '50px'});
|
||||||
}
|
}
|
||||||
else if ($(this).scrollTop() < window.loginContentStartPos && $('#login-content').css('position') != 'absolute'){
|
else if ($(this).scrollTop() < ($('#feed').offset().top-50) && $('#login-content').css('position') != 'absolute'){
|
||||||
$('#login-content, .front-signup').not('#popup-signup').css({'position': 'absolute', 'top': 'auto'});
|
$('#login-content, .front-signup').not('#popup-signup').css({'position': 'absolute', 'top': 'auto'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -123,9 +123,9 @@ if(!window.registrationsClosed) {
|
||||||
$('#signup-user-nickname-step2').after('<div class="spinner-wrap"><div class="spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div></div>');
|
$('#signup-user-nickname-step2').after('<div class="spinner-wrap"><div class="spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div></div>');
|
||||||
}
|
}
|
||||||
window.checkNicknameTimeout = setTimeout(function(){
|
window.checkNicknameTimeout = setTimeout(function(){
|
||||||
getFromAPI('check_nickname.json?nickname=' + encodeURIComponent($('#signup-user-nickname-step2').val()),function(data){
|
$.get(window.apiRoot + 'check_nickname.json?nickname=' + encodeURIComponent($('#signup-user-nickname-step2').val()),function(data){
|
||||||
$('.spinner-wrap').remove();
|
$('.spinner-wrap').remove();
|
||||||
if(data=='taken') {
|
if(data==0) {
|
||||||
$('#signup-user-password2-step2').trigger('keyup'); // revalidates
|
$('#signup-user-password2-step2').trigger('keyup'); // revalidates
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -288,6 +288,7 @@ function doLogin(streamToSet) {
|
||||||
// add user data to DOM, show search form, remeber user id, show the feed
|
// add user data to DOM, show search form, remeber user id, show the feed
|
||||||
$('#user-container').css('z-index','1000');
|
$('#user-container').css('z-index','1000');
|
||||||
$('#top-compose').removeClass('hidden');
|
$('#top-compose').removeClass('hidden');
|
||||||
|
$('#qvitter-notice').show();
|
||||||
$('#user-avatar').attr('src', window.loggedIn.profile_image_url_profile_size);
|
$('#user-avatar').attr('src', window.loggedIn.profile_image_url_profile_size);
|
||||||
$('#user-name').append(window.loggedIn.name);
|
$('#user-name').append(window.loggedIn.name);
|
||||||
$('#user-screen-name').append(window.loggedIn.screen_name);
|
$('#user-screen-name').append(window.loggedIn.screen_name);
|
||||||
|
@ -298,6 +299,7 @@ function doLogin(streamToSet) {
|
||||||
$('#user-groups strong').html(window.loggedIn.groups_count);
|
$('#user-groups strong').html(window.loggedIn.groups_count);
|
||||||
$('.stream-selection.friends-timeline').attr('href', window.loggedIn.statusnet_profile_url + '/all');
|
$('.stream-selection.friends-timeline').attr('href', window.loggedIn.statusnet_profile_url + '/all');
|
||||||
$('.stream-selection.mentions').attr('href', window.loggedIn.statusnet_profile_url + '/replies');
|
$('.stream-selection.mentions').attr('href', window.loggedIn.statusnet_profile_url + '/replies');
|
||||||
|
$('.stream-selection.notifications').attr('href', window.loggedIn.statusnet_profile_url + '/notifications');
|
||||||
$('.stream-selection.my-timeline').attr('href', window.loggedIn.statusnet_profile_url);
|
$('.stream-selection.my-timeline').attr('href', window.loggedIn.statusnet_profile_url);
|
||||||
$('.stream-selection.favorites').attr('href', window.loggedIn.statusnet_profile_url + '/favorites');
|
$('.stream-selection.favorites').attr('href', window.loggedIn.statusnet_profile_url + '/favorites');
|
||||||
window.myUserID = window.loggedIn.id;
|
window.myUserID = window.loggedIn.id;
|
||||||
|
@ -668,6 +670,12 @@ $('body').on('click','.profile-banner-footer .stats li a, .queet-stream',functio
|
||||||
else if($(this).hasClass('favorites')) {
|
else if($(this).hasClass('favorites')) {
|
||||||
setNewCurrentStream('favorites.json?screen_name=' + screenName,function(){},true);
|
setNewCurrentStream('favorites.json?screen_name=' + screenName,function(){},true);
|
||||||
}
|
}
|
||||||
|
else if($(this).hasClass('following')) {
|
||||||
|
setNewCurrentStream('statuses/friends.json?count=20',function(){},true);
|
||||||
|
}
|
||||||
|
else if($(this).hasClass('followers')) {
|
||||||
|
setNewCurrentStream('statuses/followers.json?count=20',function(){},true);
|
||||||
|
}
|
||||||
else if($(this).hasClass('member-stats')) {
|
else if($(this).hasClass('member-stats')) {
|
||||||
setNewCurrentStream('statusnet/groups/membership/' + screenName + '.json?count=20',function(){},true);
|
setNewCurrentStream('statusnet/groups/membership/' + screenName + '.json?count=20',function(){},true);
|
||||||
}
|
}
|
||||||
|
@ -737,6 +745,10 @@ $(document).on('click','a', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setNewCurrentStream('qvitter/statuses/mentions.json',function(){},true);
|
setNewCurrentStream('qvitter/statuses/mentions.json',function(){},true);
|
||||||
}
|
}
|
||||||
|
else if ($(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/' + window.loggedIn.screen_name,'') == '/notifications') {
|
||||||
|
e.preventDefault();
|
||||||
|
setNewCurrentStream('qvitter/statuses/notifications.json',function(){},true);
|
||||||
|
}
|
||||||
else if ($(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/' + window.loggedIn.screen_name,'') == '/favorites') {
|
else if ($(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/' + window.loggedIn.screen_name,'') == '/favorites') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setNewCurrentStream('favorites.json',function(){},true);
|
setNewCurrentStream('favorites.json',function(){},true);
|
||||||
|
@ -747,9 +759,6 @@ $(document).on('click','a', function(e) {
|
||||||
if($(this).parent().attr('id') == 'user-profile-link') { // logged in user
|
if($(this).parent().attr('id') == 'user-profile-link') { // logged in user
|
||||||
setNewCurrentStream('statuses/user_timeline.json?screen_name=' + window.loggedIn.screen_name,function(){},true);
|
setNewCurrentStream('statuses/user_timeline.json?screen_name=' + window.loggedIn.screen_name,function(){},true);
|
||||||
}
|
}
|
||||||
else if($(this).hasClass('account-group')) { // any user
|
|
||||||
setNewCurrentStream('statuses/user_timeline.json?screen_name=' + $(this).find('.screen-name').text().substring(1).toLowerCase(),function(){},true);
|
|
||||||
}
|
|
||||||
else { // any user
|
else { // any user
|
||||||
setNewCurrentStream('statuses/user_timeline.json?screen_name=' + $(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/',''),function(){},true);
|
setNewCurrentStream('statuses/user_timeline.json?screen_name=' + $(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/',''),function(){},true);
|
||||||
}
|
}
|
||||||
|
@ -763,6 +772,11 @@ $(document).on('click','a', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setNewCurrentStream('statusnet/tags/timeline/' + $(this).text().toLowerCase().replace('#','') + '.json',function(){},true);
|
setNewCurrentStream('statusnet/tags/timeline/' + $(this).text().toLowerCase().replace('#','') + '.json',function(){},true);
|
||||||
}
|
}
|
||||||
|
// notices
|
||||||
|
else if ($(this).attr('href').indexOf(window.siteRootDomain + '/notice/')>-1) {
|
||||||
|
e.preventDefault();
|
||||||
|
setNewCurrentStream('statuses/show/' + $(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/notice/','') + '.json',function(){},true);
|
||||||
|
}
|
||||||
// groups
|
// groups
|
||||||
else if (/^[0-9]+$/.test($(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/group/','').replace('/id',''))) {
|
else if (/^[0-9]+$/.test($(this).attr('href').replace('http://','').replace('https://','').replace(window.siteRootDomain + '/group/','').replace('/id',''))) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -1005,10 +1019,12 @@ var updateTimesInterval=self.setInterval(function(){
|
||||||
|
|
||||||
/* ·
|
/* ·
|
||||||
·
|
·
|
||||||
· Check for new queets
|
· Check for new queets and notifications
|
||||||
·
|
·
|
||||||
· · · · · · · · · · · · · */
|
· · · · · · · · · · · · · */
|
||||||
|
|
||||||
|
var checkForNewNotificationsInterval=window.setInterval(function(){checkForNewNotifications()},window.timeBetweenPolling);
|
||||||
|
checkForNewNotifications();
|
||||||
var checkForNewQueetsInterval=window.setInterval(function(){checkForNewQueets()},window.timeBetweenPolling);
|
var checkForNewQueetsInterval=window.setInterval(function(){checkForNewQueets()},window.timeBetweenPolling);
|
||||||
function checkForNewQueets() {
|
function checkForNewQueets() {
|
||||||
|
|
||||||
|
@ -1033,7 +1049,12 @@ function checkForNewQueets() {
|
||||||
// if we have hidden items, show new-queets-bar
|
// if we have hidden items, show new-queets-bar
|
||||||
if($('#feed-body').find('.stream-item.hidden').length > 0) {
|
if($('#feed-body').find('.stream-item.hidden').length > 0) {
|
||||||
var new_queets_num = $('#feed-body').find('.stream-item.hidden').length;
|
var new_queets_num = $('#feed-body').find('.stream-item.hidden').length;
|
||||||
document.title = window.siteTitle + ' (' + new_queets_num + ')';
|
|
||||||
|
// if this is notifications page, update site title with hidden notification count
|
||||||
|
if(window.currentStream == 'qvitter/statuses/notifications.json') {
|
||||||
|
document.title = window.siteTitle + ' (' + new_queets_num + ')';
|
||||||
|
}
|
||||||
|
|
||||||
$('#new-queets-bar').parent().removeClass('hidden');
|
$('#new-queets-bar').parent().removeClass('hidden');
|
||||||
|
|
||||||
// text plural
|
// text plural
|
||||||
|
@ -1050,8 +1071,6 @@ function checkForNewQueets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ·
|
/* ·
|
||||||
·
|
·
|
||||||
· Show hidden queets when user clicks on new-queets-bar
|
· Show hidden queets when user clicks on new-queets-bar
|
||||||
|
@ -1059,7 +1078,9 @@ function checkForNewQueets() {
|
||||||
· · · · · · · · · · · · · */
|
· · · · · · · · · · · · · */
|
||||||
|
|
||||||
$('body').on('click','#new-queets-bar',function(){
|
$('body').on('click','#new-queets-bar',function(){
|
||||||
document.title = window.siteTitle;
|
if(window.currentStream == 'qvitter/statuses/notifications.json') {
|
||||||
|
document.title = window.siteTitle;
|
||||||
|
}
|
||||||
$('.stream-item.hidden').css('opacity','0')
|
$('.stream-item.hidden').css('opacity','0')
|
||||||
$('.stream-item.hidden').animate({opacity:'1'}, 200);
|
$('.stream-item.hidden').animate({opacity:'1'}, 200);
|
||||||
$('.stream-item.hidden').removeClass('hidden');
|
$('.stream-item.hidden').removeClass('hidden');
|
||||||
|
@ -1819,6 +1840,7 @@ $('body').on('click','.edit-profile-button',function(){
|
||||||
</div>\
|
</div>\
|
||||||
</div>\
|
</div>\
|
||||||
</div>');
|
</div>');
|
||||||
|
$('#edit-profile-popup .profile-card').css('top',$('#page-container .profile-card').offset().top-53 + 'px'); // position exactly over
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
abortEditProfile();
|
abortEditProfile();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user