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;
|
color: silver;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar nav {
|
#around {
|
||||||
margin-bottom: 2em;
|
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;
|
float: left;
|
||||||
}
|
}
|
||||||
#sidebar nav .right {
|
#around .right {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
#sidebar nav a.disabled {
|
#around a.disabled {
|
||||||
color: silver;
|
color: silver;
|
||||||
}
|
}
|
||||||
#sidebar nav a.disabled i[class*='icon-'] {
|
#around a.disabled i[class*='icon-'] {
|
||||||
background-color: silver;
|
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
|
//core functionalities, prototypes
|
||||||
$.fn.hasAttr = function(name)
|
$.fn.hasAttr = function(name)
|
||||||
{
|
{
|
||||||
|
@ -56,6 +90,7 @@ $(function()
|
||||||
{
|
{
|
||||||
$('body').bind('dom-update', function()
|
$('body').bind('dom-update', function()
|
||||||
{
|
{
|
||||||
|
//event confirmations
|
||||||
function confirmEvent(e)
|
function confirmEvent(e)
|
||||||
{
|
{
|
||||||
if (!confirm($(this).attr('data-confirm-text')))
|
if (!confirm($(this).attr('data-confirm-text')))
|
||||||
|
@ -68,12 +103,15 @@ $(function()
|
||||||
$('form[data-confirm-text]').submit(confirmEvent);
|
$('form[data-confirm-text]').submit(confirmEvent);
|
||||||
$('a[data-confirm-text]').click(confirmEvent);
|
$('a[data-confirm-text]').click(confirmEvent);
|
||||||
|
|
||||||
|
|
||||||
|
//simple action buttons
|
||||||
$('a.simple-action').click(function(e)
|
$('a.simple-action').click(function(e)
|
||||||
{
|
{
|
||||||
if(e.isPropagationStopped())
|
if(e.isPropagationStopped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
rememberLastSearchQuery();
|
||||||
|
|
||||||
var aDom = $(this);
|
var aDom = $(this);
|
||||||
if (aDom.hasClass('inactive'))
|
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)
|
$('form.edit-post').submit(function(e)
|
||||||
{
|
{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
rememberLastSearchQuery();
|
||||||
|
|
||||||
var formDom = $(this);
|
var formDom = $(this);
|
||||||
if (formDom.hasClass('inactive'))
|
if (formDom.hasClass('inactive'))
|
||||||
|
@ -102,6 +103,7 @@ $(function()
|
||||||
$('form.add-comment').submit(function(e)
|
$('form.add-comment').submit(function(e)
|
||||||
{
|
{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
rememberLastSearchQuery();
|
||||||
|
|
||||||
var formDom = $(this);
|
var formDom = $(this);
|
||||||
if (formDom.hasClass('inactive'))
|
if (formDom.hasClass('inactive'))
|
||||||
|
@ -166,7 +168,7 @@ $(function()
|
||||||
$.ajax(ajaxData);
|
$.ajax(ajaxData);
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind('a', function() { var url = $('#sidebar .left 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 url = $('#sidebar .right a').attr('href'); if (typeof url !== 'undefined') 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');
|
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)
|
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-small.css';
|
||||||
$this->context->stylesheets []= 'post-list.css';
|
$this->context->stylesheets []= 'post-list.css';
|
||||||
$this->context->stylesheets []= 'tabs.css';
|
$this->context->stylesheets []= 'tabs.css';
|
||||||
$this->context->stylesheets []= 'paginator.css';
|
$this->context->stylesheets []= 'paginator.css';
|
||||||
$this->context->viewName = 'post-list-wrapper';
|
$this->context->scripts []= 'post-list.js';
|
||||||
if ($this->context->user->hasEnabledEndlessScrolling())
|
if ($this->context->user->hasEnabledEndlessScrolling())
|
||||||
$this->context->scripts []= 'paginator-endless.js';
|
$this->context->scripts []= 'paginator-endless.js';
|
||||||
if ($source == 'mass-tag')
|
|
||||||
$this->context->scripts []= 'mass-tag.js';
|
|
||||||
$this->context->source = $source;
|
$this->context->source = $source;
|
||||||
$this->context->additionalInfo = $additionalInfo;
|
$this->context->additionalInfo = $additionalInfo;
|
||||||
|
|
||||||
|
@ -83,6 +82,7 @@ class PostController
|
||||||
if ($formQuery !== null)
|
if ($formQuery !== null)
|
||||||
{
|
{
|
||||||
$this->context->transport->searchQuery = $formQuery;
|
$this->context->transport->searchQuery = $formQuery;
|
||||||
|
$this->context->transport->lastSearchQuery = $formQuery;
|
||||||
if (strpos($formQuery, '/') !== false)
|
if (strpos($formQuery, '/') !== false)
|
||||||
throw new SimpleException('Search query contains invalid characters');
|
throw new SimpleException('Search query contains invalid characters');
|
||||||
$url = \Chibi\UrlHelper::route('post', 'list', ['source' => $source, 'additionalInfo' => $additionalInfo, 'query' => $formQuery]);
|
$url = \Chibi\UrlHelper::route('post', 'list', ['source' => $source, 'additionalInfo' => $additionalInfo, 'query' => $formQuery]);
|
||||||
|
@ -95,6 +95,7 @@ class PostController
|
||||||
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
$postsPerPage = intval($this->config->browsing->postsPerPage);
|
||||||
$this->context->subTitle = 'posts';
|
$this->context->subTitle = 'posts';
|
||||||
$this->context->transport->searchQuery = $query;
|
$this->context->transport->searchQuery = $query;
|
||||||
|
$this->context->transport->lastSearchQuery = $query;
|
||||||
PrivilegesHelper::confirmWithException(Privilege::ListPosts);
|
PrivilegesHelper::confirmWithException(Privilege::ListPosts);
|
||||||
if ($source == 'mass-tag')
|
if ($source == 'mass-tag')
|
||||||
{
|
{
|
||||||
|
@ -444,38 +445,19 @@ class PostController
|
||||||
'comment',
|
'comment',
|
||||||
'ownComment.commenter' => 'user']);
|
'ownComment.commenter' => 'user']);
|
||||||
|
|
||||||
|
$this->context->transport->lastSearchQuery = InputHelper::get('last-search-query');
|
||||||
|
|
||||||
if ($post->hidden)
|
if ($post->hidden)
|
||||||
PrivilegesHelper::confirmWithException(Privilege::ViewPost, 'hidden');
|
PrivilegesHelper::confirmWithException(Privilege::ViewPost, 'hidden');
|
||||||
PrivilegesHelper::confirmWithException(Privilege::ViewPost);
|
PrivilegesHelper::confirmWithException(Privilege::ViewPost);
|
||||||
PrivilegesHelper::confirmWithException(Privilege::ViewPost, PostSafety::toString($post->safety));
|
PrivilegesHelper::confirmWithException(Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||||
|
|
||||||
$buildNextPostQuery = function($dbQuery, $id, $next)
|
Model_Post_QueryBuilder::enableTokenLimit(false);
|
||||||
{
|
$prevPostQuery = $this->context->transport->lastSearchQuery . ' prev:' . $id;
|
||||||
$dbQuery->select('id')
|
$nextPostQuery = $this->context->transport->lastSearchQuery . ' next:' . $id;
|
||||||
->from('post')
|
$prevPost = current(Model_Post::getEntities($prevPostQuery, 1, 1));
|
||||||
->where($next ? 'id > ?' : 'id < ?')
|
$nextPost = current(Model_Post::getEntities($nextPostQuery, 1, 1));
|
||||||
->put($id);
|
Model_Post_QueryBuilder::enableTokenLimit(true);
|
||||||
$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');
|
|
||||||
|
|
||||||
$favorite = $this->context->user->hasFavorited($post);
|
$favorite = $this->context->user->hasFavorited($post);
|
||||||
$score = $this->context->user->getScore($post);
|
$score = $this->context->user->getScore($post);
|
||||||
|
|
|
@ -425,6 +425,7 @@ class UserController
|
||||||
$this->context->stylesheets []= 'post-list.css';
|
$this->context->stylesheets []= 'post-list.css';
|
||||||
$this->context->stylesheets []= 'post-small.css';
|
$this->context->stylesheets []= 'post-small.css';
|
||||||
$this->context->stylesheets []= 'paginator.css';
|
$this->context->stylesheets []= 'paginator.css';
|
||||||
|
$this->context->scripts []= 'post-list.js';
|
||||||
if ($this->context->user->hasEnabledEndlessScrolling())
|
if ($this->context->user->hasEnabledEndlessScrolling())
|
||||||
$this->context->scripts []= 'paginator-endless.js';
|
$this->context->scripts []= 'paginator-endless.js';
|
||||||
|
|
||||||
|
@ -442,6 +443,7 @@ class UserController
|
||||||
$posts = Model_Post::getEntities($query, $postsPerPage, $page);
|
$posts = Model_Post::getEntities($query, $postsPerPage, $page);
|
||||||
|
|
||||||
$this->context->transport->tab = $tab;
|
$this->context->transport->tab = $tab;
|
||||||
|
$this->context->transport->lastSearchQuery = $query;
|
||||||
$this->context->transport->paginator = new StdClass;
|
$this->context->transport->paginator = new StdClass;
|
||||||
$this->context->transport->paginator->page = $page;
|
$this->context->transport->paginator->page = $page;
|
||||||
$this->context->transport->paginator->pageCount = $pageCount;
|
$this->context->transport->paginator->pageCount = $pageCount;
|
||||||
|
|
|
@ -268,11 +268,44 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
|
||||||
return self::filterTokenSubmit($context, $dbQuery, $val);
|
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)
|
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') ?>"/>
|
<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>
|
</form>
|
||||||
</li>
|
</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>
|
</ul>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
<nav>
|
<nav id="around">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<?php if ($this->context->transport->nextPostId): ?>
|
<?php if ($this->context->transport->nextPostId): ?>
|
||||||
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $this->context->transport->nextPostId]) ?>">
|
<a href="<?php echo \Chibi\UrlHelper::route('post', 'view', ['id' => $this->context->transport->nextPostId]) ?>">
|
||||||
|
@ -23,6 +23,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="clear"></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>
|
</nav>
|
||||||
|
|
||||||
<div class="unit tags">
|
<div class="unit tags">
|
||||||
|
|
Loading…
Reference in a new issue