Next/prev links are bound to latest search query
This commit is contained in:
parent
d461a88001
commit
20022ea4ab
9 changed files with 121 additions and 40 deletions
|
@ -31,19 +31,26 @@ embed {
|
|||
color: silver;
|
||||
}
|
||||
|
||||
#sidebar nav {
|
||||
#around {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
#sidebar nav .left {
|
||||
#around .text {
|
||||
font-size: 90%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
margin-top: 0.75em;
|
||||
}
|
||||
#around .left {
|
||||
float: left;
|
||||
}
|
||||
#sidebar nav .right {
|
||||
#around .right {
|
||||
float: right;
|
||||
}
|
||||
#sidebar nav a.disabled {
|
||||
#around a.disabled {
|
||||
color: silver;
|
||||
}
|
||||
#sidebar nav a.disabled i[class*='icon-'] {
|
||||
#around a.disabled i[class*='icon-'] {
|
||||
background-color: silver;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,37 @@
|
|||
function setCookie(name, value, exdays)
|
||||
{
|
||||
var exdate = new Date();
|
||||
exdate.setDate(exdate.getDate() + exdays);
|
||||
value = escape(value) + '; path=/' + ((exdays == null) ? '' : '; expires=' + exdate.toUTCString());
|
||||
document.cookie = name + '=' + value;
|
||||
}
|
||||
|
||||
function getCookie(name)
|
||||
{
|
||||
console.log(document.cookie);
|
||||
var value = document.cookie;
|
||||
var start = value.indexOf(' ' + name + '=');
|
||||
|
||||
if (start == -1)
|
||||
start = value.indexOf(name + '=');
|
||||
|
||||
if (start == -1)
|
||||
return null;
|
||||
|
||||
start = value.indexOf('=', start) + 1;
|
||||
var end = value.indexOf(";", start);
|
||||
if (end == -1)
|
||||
end = value.length;
|
||||
|
||||
return unescape(value.substring(start, end));
|
||||
}
|
||||
|
||||
function rememberLastSearchQuery()
|
||||
{
|
||||
//lastSearchQuery variable is obtained from layout
|
||||
setCookie('last-search-query', lastSearchQuery);
|
||||
}
|
||||
|
||||
//core functionalities, prototypes
|
||||
$.fn.hasAttr = function(name)
|
||||
{
|
||||
|
@ -56,6 +90,7 @@ $(function()
|
|||
{
|
||||
$('body').bind('dom-update', function()
|
||||
{
|
||||
//event confirmations
|
||||
function confirmEvent(e)
|
||||
{
|
||||
if (!confirm($(this).attr('data-confirm-text')))
|
||||
|
@ -68,12 +103,15 @@ $(function()
|
|||
$('form[data-confirm-text]').submit(confirmEvent);
|
||||
$('a[data-confirm-text]').click(confirmEvent);
|
||||
|
||||
|
||||
//simple action buttons
|
||||
$('a.simple-action').click(function(e)
|
||||
{
|
||||
if(e.isPropagationStopped())
|
||||
return;
|
||||
|
||||
e.preventDefault();
|
||||
rememberLastSearchQuery();
|
||||
|
||||
var aDom = $(this);
|
||||
if (aDom.hasClass('inactive'))
|
||||
|
@ -116,6 +154,10 @@ $(function()
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//try to remember last search query
|
||||
window.onbeforeunload = rememberLastSearchQuery;
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ $(function()
|
|||
$('form.edit-post').submit(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
rememberLastSearchQuery();
|
||||
|
||||
var formDom = $(this);
|
||||
if (formDom.hasClass('inactive'))
|
||||
|
@ -102,6 +103,7 @@ $(function()
|
|||
$('form.add-comment').submit(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
rememberLastSearchQuery();
|
||||
|
||||
var formDom = $(this);
|
||||
if (formDom.hasClass('inactive'))
|
||||
|
@ -166,7 +168,7 @@ $(function()
|
|||
$.ajax(ajaxData);
|
||||
});
|
||||
|
||||
Mousetrap.bind('a', function() { var url = $('#sidebar .left a').attr('href'); if (typeof url !== 'undefined') window.location.href = url; }, 'keyup');
|
||||
Mousetrap.bind('d', function() { var url = $('#sidebar .right a').attr('href'); if (typeof url !== 'undefined') window.location.href = url; }, 'keyup');
|
||||
Mousetrap.bind('a', function() { var a = $('#sidebar .left a'); var url = a.attr('href'); if (typeof url !== 'undefined') { a.click(); window.location.href = url; } }, 'keyup');
|
||||
Mousetrap.bind('d', function() { var a = $('#sidebar .right a'); var url = a.attr('href'); if (typeof url !== 'undefined') { a.click(); window.location.href = url; } }, 'keyup');
|
||||
Mousetrap.bind('e', function() { $('li.edit a').trigger('click'); return false; }, 'keyup');
|
||||
});
|
||||
|
|
|
@ -66,15 +66,14 @@ class PostController
|
|||
*/
|
||||
public function listAction($query = null, $page = 1, $source = 'posts', $additionalInfo = null)
|
||||
{
|
||||
$this->context->viewName = 'post-list-wrapper';
|
||||
$this->context->stylesheets []= 'post-small.css';
|
||||
$this->context->stylesheets []= 'post-list.css';
|
||||
$this->context->stylesheets []= 'tabs.css';
|
||||
$this->context->stylesheets []= 'paginator.css';
|
||||
$this->context->viewName = 'post-list-wrapper';
|
||||
$this->context->scripts []= 'post-list.js';
|
||||
if ($this->context->user->hasEnabledEndlessScrolling())
|
||||
$this->context->scripts []= 'paginator-endless.js';
|
||||
if ($source == 'mass-tag')
|
||||
$this->context->scripts []= 'mass-tag.js';
|
||||
$this->context->source = $source;
|
||||
$this->context->additionalInfo = $additionalInfo;
|
||||
|
||||
|
@ -83,6 +82,7 @@ class PostController
|
|||
if ($formQuery !== null)
|
||||
{
|
||||
$this->context->transport->searchQuery = $formQuery;
|
||||
$this->context->transport->lastSearchQuery = $formQuery;
|
||||
if (strpos($formQuery, '/') !== false)
|
||||
throw new SimpleException('Search query contains invalid characters');
|
||||
$url = \Chibi\UrlHelper::route('post', 'list', ['source' => $source, 'additionalInfo' => $additionalInfo, 'query' => $formQuery]);
|
||||
|
@ -95,6 +95,7 @@ class PostController
|
|||
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
||||
$this->context->subTitle = 'posts';
|
||||
$this->context->transport->searchQuery = $query;
|
||||
$this->context->transport->lastSearchQuery = $query;
|
||||
PrivilegesHelper::confirmWithException(Privilege::ListPosts);
|
||||
if ($source == 'mass-tag')
|
||||
{
|
||||
|
@ -444,38 +445,19 @@ class PostController
|
|||
'comment',
|
||||
'ownComment.commenter' => 'user']);
|
||||
|
||||
$this->context->transport->lastSearchQuery = InputHelper::get('last-search-query');
|
||||
|
||||
if ($post->hidden)
|
||||
PrivilegesHelper::confirmWithException(Privilege::ViewPost, 'hidden');
|
||||
PrivilegesHelper::confirmWithException(Privilege::ViewPost);
|
||||
PrivilegesHelper::confirmWithException(Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||
|
||||
$buildNextPostQuery = function($dbQuery, $id, $next)
|
||||
{
|
||||
$dbQuery->select('id')
|
||||
->from('post')
|
||||
->where($next ? 'id > ?' : 'id < ?')
|
||||
->put($id);
|
||||
$allowedSafety = array_filter(PostSafety::getAll(), function($safety)
|
||||
{
|
||||
return PrivilegesHelper::confirm(Privilege::ListPosts, PostSafety::toString($safety)) and
|
||||
$this->context->user->hasEnabledSafety($safety);
|
||||
});
|
||||
$dbQuery->and('safety')->in('(' . R::genSlots($allowedSafety) . ')');
|
||||
foreach ($allowedSafety as $s)
|
||||
$dbQuery->put($s);
|
||||
if (!PrivilegesHelper::confirm(Privilege::ListPosts, 'hidden'))
|
||||
$dbQuery->andNot('hidden');
|
||||
$dbQuery->orderBy($next ? 'id asc' : 'id desc')
|
||||
->limit(1);
|
||||
};
|
||||
|
||||
$prevPostQuery = R::$f->begin();
|
||||
$buildNextPostQuery($prevPostQuery, $id, false);
|
||||
$prevPost = $prevPostQuery->get('row');
|
||||
|
||||
$nextPostQuery = R::$f->begin();
|
||||
$buildNextPostQuery($nextPostQuery, $id, true);
|
||||
$nextPost = $nextPostQuery->get('row');
|
||||
Model_Post_QueryBuilder::enableTokenLimit(false);
|
||||
$prevPostQuery = $this->context->transport->lastSearchQuery . ' prev:' . $id;
|
||||
$nextPostQuery = $this->context->transport->lastSearchQuery . ' next:' . $id;
|
||||
$prevPost = current(Model_Post::getEntities($prevPostQuery, 1, 1));
|
||||
$nextPost = current(Model_Post::getEntities($nextPostQuery, 1, 1));
|
||||
Model_Post_QueryBuilder::enableTokenLimit(true);
|
||||
|
||||
$favorite = $this->context->user->hasFavorited($post);
|
||||
$score = $this->context->user->getScore($post);
|
||||
|
|
|
@ -425,6 +425,7 @@ class UserController
|
|||
$this->context->stylesheets []= 'post-list.css';
|
||||
$this->context->stylesheets []= 'post-small.css';
|
||||
$this->context->stylesheets []= 'paginator.css';
|
||||
$this->context->scripts []= 'post-list.js';
|
||||
if ($this->context->user->hasEnabledEndlessScrolling())
|
||||
$this->context->scripts []= 'paginator-endless.js';
|
||||
|
||||
|
@ -442,6 +443,7 @@ class UserController
|
|||
$posts = Model_Post::getEntities($query, $postsPerPage, $page);
|
||||
|
||||
$this->context->transport->tab = $tab;
|
||||
$this->context->transport->lastSearchQuery = $query;
|
||||
$this->context->transport->paginator = new StdClass;
|
||||
$this->context->transport->paginator->page = $page;
|
||||
$this->context->transport->paginator->pageCount = $pageCount;
|
||||
|
|
|
@ -268,11 +268,44 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
|
|||
return self::filterTokenSubmit($context, $dbQuery, $val);
|
||||
}
|
||||
|
||||
protected static function filterTokenUploaded($dbQuery, $val)
|
||||
protected static function filterTokenPrev($context, $dbQuery, $val)
|
||||
{
|
||||
return self::filterTokenSubmit($dbQuery, $val);
|
||||
self::__filterTokenPrevNext($context, $dbQuery, $val);
|
||||
}
|
||||
|
||||
protected static function filterTokenNext($context, $dbQuery, $val)
|
||||
{
|
||||
$context->orderDir *= -1;
|
||||
self::__filterTokenPrevNext($context, $dbQuery, $val);
|
||||
}
|
||||
|
||||
protected static function __filterTokenPrevNext($context, $dbQuery, $val)
|
||||
{
|
||||
$op1 = $context->orderDir == 1 ? '<' : '>';
|
||||
$op2 = $context->orderDir != 1 ? '<' : '>';
|
||||
$dbQuery
|
||||
->open()
|
||||
->open()
|
||||
->addSql($context->orderColumn . ' ' . $op1 . ' ')
|
||||
->open()
|
||||
->select($context->orderColumn)
|
||||
->from('post p2')
|
||||
->where('p2.id = ?')->put(intval($val))
|
||||
->close()
|
||||
->and('id != ?')->put($val)
|
||||
->close()
|
||||
->or()
|
||||
->open()
|
||||
->addSql($context->orderColumn . ' = ')
|
||||
->open()
|
||||
->select($context->orderColumn)
|
||||
->from('post p2')
|
||||
->where('p2.id = ?')->put(intval($val))
|
||||
->close()
|
||||
->and('id ' . $op1 . ' ?')->put(intval($val))
|
||||
->close()
|
||||
->close();
|
||||
}
|
||||
|
||||
|
||||
protected static function parseOrderToken($context, $val)
|
||||
|
|
|
@ -90,6 +90,12 @@
|
|||
<input type="search" name="query" placeholder="Search…" value="<?php echo isset($this->context->transport->searchQuery) ? htmlspecialchars($this->context->transport->searchQuery) : '' ?>" data-autocomplete-url="<?php echo \Chibi\UrlHelper::route('tag', 'list') ?>"/>
|
||||
</form>
|
||||
</li>
|
||||
|
||||
<?php if (isset($this->context->transport->lastSearchQuery)): ?>
|
||||
<script type="text/javascript">
|
||||
var lastSearchQuery = <?php echo json_encode($this->context->transport->lastSearchQuery) ?>;
|
||||
</script>
|
||||
<?php endif ?>
|
||||
</ul>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div id="sidebar">
|
||||
<nav>
|
||||
<nav id="around">
|
||||
<div class="left">
|
||||
<?php if ($this->context->transport->nextPostId): ?>
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $this->context->transport->nextPostId]) ?>">
|
||||
|
@ -23,6 +23,13 @@
|
|||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<?php if (!empty($this->context->transport->lastSearchQuery)): ?>
|
||||
<div class="text">
|
||||
Current search:<br/>
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'list', ['query' => $this->context->transport->lastSearchQuery]) ?>"><?php echo $this->context->transport->lastSearchQuery ?></a>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</nav>
|
||||
|
||||
<div class="unit tags">
|
||||
|
|
Loading…
Reference in a new issue