Commit c01a5b8f authored by Evan Prodromou's avatar Evan Prodromou

Merge branch '0.8.x' of git@gitorious.org:statusnet/mainline into 0.8.x

parents e80fad7a acd5a532
......@@ -380,8 +380,13 @@ class ShowstreamAction extends ProfileAction
$this->showEmptyListMessage();
}
$args = array('nickname' => $this->user->nickname);
if (!empty($this->tag))
{
$args['tag'] = $this->tag;
}
$this->pagination($this->page>1, $cnt>NOTICES_PER_PAGE, $this->page,
'showstream', array('nickname' => $this->user->nickname));
'showstream', $args);
}
function showAnonymousMessage()
......
......@@ -136,6 +136,11 @@ class TwitapistatusesAction extends TwitterapiAction
}
function home_timeline($args, $apidata)
{
call_user_func(array($this, 'friends_timeline'), $args, $apidata);
}
function user_timeline($args, $apidata)
{
parent::handle($args);
......
......@@ -120,11 +120,15 @@ class User extends Memcached_DataObject
function allowed_nickname($nickname)
{
// XXX: should already be validated for size, content, etc.
static $blacklist = array('rss', 'xrds', 'doc', 'main',
'settings', 'notice', 'user',
'search', 'avatar', 'tag', 'tags',
'api', 'message', 'group', 'groups',
'local');
$blacklist = array();
//all directory and file names should be blacklisted
$d = dir(INSTALLDIR);
while (false !== ($entry = $d->read())) {
$blacklist[]=$entry;
}
$d->close();
$merged = array_merge($blacklist, common_config('nickname', 'blacklist'));
return !in_array($nickname, $merged);
}
......
......@@ -37,10 +37,10 @@ currently-implemented commands:
* **help**: Show this help. List available Jabber/XMPP commands
* **follow <nickname>**: Subscribe to <nickname>
* **sub <nickname>**: Same as follow
* **leave <nickname>**: Subscribe to <nickname>
* **leave <nickname>**: Unsubscribe from <nickname>
* **unsub <nickname>**: Same as leave
* **d <nickname> <text>**: Send direct message to <nickname> with message body <text>
* **get <nickname>**: Get last notice from <nickname>
* **last <nickname>**: Same as 'get'
* **whois <nickname>**: Get Profile info on <nickname>
* **fav <nickname>**: Add user's last notice as a favorite
\ No newline at end of file
* **fav <nickname>**: Add user's last notice as a favorite
......@@ -325,7 +325,6 @@ class DesignSettingsAction extends AccountSettingsAction
parent::showScripts();
$this->script('js/farbtastic/farbtastic.js');
$this->script('js/farbtastic/farbtastic.go.js');
$this->script('js/userdesign.go.js');
$this->autofocus('design_background-image_file');
......
......@@ -261,7 +261,7 @@ class NoticeListItem extends Widget
$attrs = array('href' => $this->profile->profileurl,
'class' => 'url');
if (!empty($this->profile->fullname)) {
$attrs['title'] = $this->profile->fullname . ' (' . $this->profile->nickname . ') ';
$attrs['title'] = $this->profile->fullname . ' (' . $this->profile->nickname . ')';
}
$this->out->elementStart('a', $attrs);
$this->showAvatar();
......@@ -418,9 +418,17 @@ class NoticeListItem extends Widget
function showContext()
{
// XXX: also show context if there are replies to this notice
if (!empty($this->notice->conversation)
&& $this->notice->conversation != $this->notice->id) {
$hasConversation = false;
if( !empty($this->notice->conversation)
&& $this->notice->conversation != $this->notice->id){
$hasConversation = true;
}else{
$conversation = Notice::conversationStream($this->notice->id, 1, 1);
if($conversation->N > 0){
$hasConversation = true;
}
}
if ($hasConversation){
$convurl = common_local_url('conversation',
array('id' => $this->notice->conversation));
$this->out->element('a', array('href' => $convurl.'#notice-'.$this->notice->id,
......
......@@ -272,12 +272,12 @@ class Router
$m->connect('api/statuses/:method',
array('action' => 'api',
'apiaction' => 'statuses'),
array('method' => '(public_timeline|friends_timeline|user_timeline|update|replies|mentions|show|friends|followers|featured)(\.(atom|rss|xml|json))?'));
array('method' => '(public_timeline|home_timeline|friends_timeline|user_timeline|update|replies|mentions|show|friends|followers|featured)(\.(atom|rss|xml|json))?'));
$m->connect('api/statuses/:method/:argument',
array('action' => 'api',
'apiaction' => 'statuses'),
array('method' => '(|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
array('method' => '(user_timeline|home_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
// users
......@@ -436,7 +436,7 @@ class Router
$m->connect('api/statuses/:method/:argument',
array('action' => 'api',
'apiaction' => 'statuses'),
array('method' => '(|user_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
array('method' => '(user_timeline|home_timeline|friends_timeline|replies|mentions|show|destroy|friends|followers)'));
$m->connect('api/statusnet/groups/:method/:argument',
array('action' => 'api',
......
Autocomplete allows users to autocomplete screen names in @ replies. When an "@" is typed into the notice text area, an autocomplete box is displayed populated with the user's friends' screen names.
Note: This plugin doesn't work if the site is in Private mode, i.e. when $config['site']['private'] is set to true.
Installation
============
Add "addPlugin('Autocomplete');" to the bottom of your config.php
......
......@@ -40,7 +40,7 @@ class InfiniteScrollPlugin extends Plugin
function onEndShowScripts($action)
{
$action->script('plugins/InfiniteScroll/jquery.infinitescroll.min.js');
$action->script('plugins/InfiniteScroll/jquery.infinitescroll.js');
$action->script('plugins/InfiniteScroll/infinitescroll.js');
}
}
jQuery(document).ready(function($){
$('notices_primary').infinitescroll({
debug: true,
infiniteScroll : false,
nextSelector : "li.nav_next a",
loadingImg : $('address .url')[0].href+'plugins/InfiniteScroll/ajax-loader.gif',
text : "<em>Loading the next set of posts...</em>",
......@@ -12,4 +13,3 @@ jQuery(document).ready(function($){
NoticeAttachments();
});
});
......@@ -92,14 +92,14 @@
if (props.isDuringAjax || props.isInvalidPage || props.isDone) return;
if ( !isNearBottom(opts,props) ) return;
if ( opts.infiniteScroll && !isNearBottom(opts,props) ) return;
// we dont want to fire the ajax multiple times
props.isDuringAjax = true;
// show the loading message and hide the previous/next links
props.loadingMsg.appendTo( opts.contentSelector ).show();
$( opts.navSelector ).hide();
if(opts.infiniteScroll) $( opts.navSelector ).hide();
// increment the URL bit. e.g. /page/3/
props.currPage++;
......@@ -205,10 +205,19 @@
}
});
// bind scroll handler to element (if its a local scroll) or window
$(opts.localMode ? this : window)
.bind('scroll.infscr', function(){ infscrSetup(path,opts,props,callback); } )
.trigger('scroll.infscr'); // trigger the event, in case it's a short page
if(opts.infiniteScroll){
// bind scroll handler to element (if its a local scroll) or window
$(opts.localMode ? this : window)
.bind('scroll.infscr', function(){ infscrSetup(path,opts,props,callback); } )
.trigger('scroll.infscr'); // trigger the event, in case it's a short page
}else{
$(opts.nextSelector).click(
function(){
infscrSetup(path,opts,props,callback);
return false;
}
);
}
return this;
......@@ -222,6 +231,7 @@
$.infinitescroll = {
defaults : {
debug : false,
infiniteScroll : true,
preload : false,
nextSelector : "div.navigation a:first",
loadingImg : "http://www.infinite-scroll.com/loading.gif",
......
// update the local timeline from a Meteor server
//
// Update the local timeline from a Meteor server
// XXX: If @a is subscribed to @b, @a should get @b's notices in @a's Personal timeline.
// Do Replies timeline.
var MeteorUpdater = function()
{
return {
init: function(server, port, timeline)
{
Meteor.callbacks["process"] = function(data) {
RealtimeUpdate.receive(JSON.parse(data));
};
Meteor.host = server;
Meteor.port = port;
Meteor.joinChannel(timeline, 0);
Meteor.connect();
}
}
return {
init: function(server, port, timeline)
{
Meteor.callbacks["process"] = function(data) {
var d = JSON.parse(data);
var user_url = $('address .url')[0].href+d['user']['screen_name'];
var wlh = window.location.href;
if (wlh.indexOf('?') > 0) {
wlh = wlh.slice(0, wlh.indexOf('?'))
}
if (timeline == 'public' ||
user_url+'/all' == wlh ||
user_url == wlh) {
RealtimeUpdate.receive(d);
}
};
Meteor.host = server;
Meteor.port = port;
Meteor.joinChannel(timeline, 0);
Meteor.connect();
}
}
}();
......@@ -63,20 +63,22 @@ class RealtimePlugin extends Plugin
{
$path = null;
switch ($action->trimmed('action')) {
case 'public':
$path = array('public');
break;
case 'tag':
$tag = $action->trimmed('tag');
if (!empty($tag)) {
$path = array('tag', $tag);
} else {
$a = $action->trimmed('action');
switch ($a) {
case 'public': case 'all': case 'replies': case 'showstream':
$path = array($a);
break;
case 'tag':
$tag = $action->trimmed('tag');
if (!empty($tag)) {
$path = array('tag', $tag);
} else {
return true;
}
break;
default:
return true;
}
break;
default:
return true;
}
$timeline = $this->_pathToChannel($path);
......@@ -95,10 +97,16 @@ class RealtimePlugin extends Plugin
$user_id = 0;
}
$action->script('plugins/Realtime/jquery.getUrlParam.js');
$action->elementStart('script', array('type' => 'text/javascript'));
$action->raw("$(document).ready(function() { ");
$action->raw($this->_updateInitialize($timeline, $user_id));
$action->raw(" });");
$action->raw('
<!--
$(document).ready(function() {
' . $this->_updateInitialize($timeline, $user_id) . '
});
-->
');
$action->elementEnd('script');
return true;
......@@ -108,11 +116,13 @@ class RealtimePlugin extends Plugin
{
$paths = array();
// XXX: Add other timelines; this is just for the public one
// TODO: Replies timeline
if ($notice->is_local ||
($notice->is_local == 0 && !common_config('public', 'localonly'))) {
$paths[] = array('public');
foreach (array('public', 'all', 'replies', 'showstream') as $a) {
$paths[] = array($a);
}
}
$tags = $this->getNoticeTags($notice);
......
/* Copyright (c) 2006-2007 Mathias Bank (http://www.mathias-bank.de)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Version 2.1
*
* Thanks to
* Hinnerk Ruemenapf - http://hinnerk.ruemenapf.de/ for bug reporting and fixing.
* Tom Leonard for some improvements
*
*/
jQuery.fn.extend({
/**
* Returns get parameters.
*
* If the desired param does not exist, null will be returned
*
* To get the document params:
* @example value = $(document).getUrlParam("paramName");
*
* To get the params of a html-attribut (uses src attribute)
* @example value = $('#imgLink').getUrlParam("paramName");
*/
getUrlParam: function(strParamName){
strParamName = escape(unescape(strParamName));
var returnVal = new Array();
var qString = null;
if ($(this).attr("nodeName")=="#document") {
//document-handler
if (window.location.search.search(strParamName) > -1 ){
qString = window.location.search.substr(1,window.location.search.length).split("&");
}
} else if ($(this).attr("src")!="undefined") {
var strHref = $(this).attr("src")
if ( strHref.indexOf("?") > -1 ){
var strQueryString = strHref.substr(strHref.indexOf("?")+1);
qString = strQueryString.split("&");
}
} else if ($(this).attr("href")!="undefined") {
var strHref = $(this).attr("href")
if ( strHref.indexOf("?") > -1 ){
var strQueryString = strHref.substr(strHref.indexOf("?")+1);
qString = strQueryString.split("&");
}
} else {
return null;
}
if (qString==null) return null;
for (var i=0;i<qString.length; i++){
if (escape(unescape(qString[i].split("=")[0])) == strParamName){
returnVal.push(qString[i].split("=")[1]);
}
}
if (returnVal.length==0) return null;
else if (returnVal.length==1) return returnVal[0];
else return returnVal;
}
});
\ No newline at end of file
This diff is collapsed.
......@@ -6,7 +6,7 @@ Use:
1. Get an API key from http://recaptcha.net
2. In config.php add:
include_once('plugins/recaptcha.php');
include_once('plugins/recaptcha/recaptcha.php');
$captcha = new recaptcha(publickey, privatekey, showErrors);
Changelog
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment