diff --git a/client/css/pool-navigator-control.styl b/client/css/pool-navigator-control.styl
new file mode 100644
index 00000000..56c22d28
--- /dev/null
+++ b/client/css/pool-navigator-control.styl
@@ -0,0 +1,34 @@
+@import colors
+
+.pool-navigator-container
+ padding: 0
+ margin: 0 auto
+
+ .pool-info-wrapper
+ box-sizing: border-box
+ width: 100%
+ margin: 0 0 1em 0
+ display: flex
+ padding: 0.5em 1em
+ border: 1px solid $pool-navigator-border-color
+ background: $pool-navigator-background-color
+
+ .pool-name
+ flex: 1 1;
+ text-align: center;
+ overflow: hidden;
+ white-space: nowrap;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+
+ .first, .last
+ flex-basis: 1em;
+
+ .first, .prev, .next, .last
+ flex: 0 1;
+ margin: 0 .25em;
+ white-space: nowrap;
+
+
+.darktheme .pool-navigator-container
+ background: $pool-navigator-header-background-color-darktheme
\ No newline at end of file
diff --git a/client/css/pool-navigator-list.styl b/client/css/pool-navigator-list.styl
new file mode 100644
index 00000000..080ad01a
--- /dev/null
+++ b/client/css/pool-navigator-list.styl
@@ -0,0 +1,9 @@
+.pool-navigators>ul
+ list-style-type: none
+ margin: 0
+ padding: 0
+
+ >li
+ margin-bottom: 1em
+ &:last-child
+ margin-bottom: 0
diff --git a/client/html/pool_navigator.tpl b/client/html/pool_navigator.tpl
new file mode 100644
index 00000000..647684d8
--- /dev/null
+++ b/client/html/pool_navigator.tpl
@@ -0,0 +1,49 @@
+
+ <% if (ctx.canListPools && ctx.canViewPools) { %>
+
+ <% } %>
+
<% if (ctx.canListComments) { %>
<% } %>
diff --git a/client/js/controllers/post_main_controller.js b/client/js/controllers/post_main_controller.js
index 95cfdb52..b60a1686 100644
--- a/client/js/controllers/post_main_controller.js
+++ b/client/js/controllers/post_main_controller.js
@@ -11,11 +11,17 @@ const PostList = require("../models/post_list.js");
const PostMainView = require("../views/post_main_view.js");
const BasePostController = require("./base_post_controller.js");
const EmptyView = require("../views/empty_view.js");
+const PoolNavigatorListControl = require("../controls/pool_navigator_list_control.js");
class PostMainController extends BasePostController {
constructor(ctx, editMode) {
super(ctx);
+ let poolPostsNearby = Promise.resolve({results: []});
+ if (api.hasPrivilege("pools:list") && api.hasPrivilege("pools:view")) {
+ poolPostsNearby = PostList.getNearbyPoolPosts(ctx.parameters.id)
+ }
+
let parameters = ctx.parameters;
Promise.all([
Post.get(ctx.parameters.id),
@@ -23,9 +29,10 @@ class PostMainController extends BasePostController {
ctx.parameters.id,
parameters ? parameters.query : null
),
+ poolPostsNearby
]).then(
(responses) => {
- const [post, aroundResponse] = responses;
+ const [post, aroundResponse, poolPostsNearby] = responses;
// remove junk from query, but save it into history so that it can
// be still accessed after history navigation / page refresh
@@ -44,6 +51,7 @@ class PostMainController extends BasePostController {
this._post = post;
this._view = new PostMainView({
post: post,
+ poolPostsNearby: poolPostsNearby,
editMode: editMode,
prevPostId: aroundResponse.prev
? aroundResponse.prev.id
@@ -56,6 +64,8 @@ class PostMainController extends BasePostController {
canFeaturePosts: api.hasPrivilege("posts:feature"),
canListComments: api.hasPrivilege("comments:list"),
canCreateComments: api.hasPrivilege("comments:create"),
+ canListPools: api.hasPrivilege("pools:list"),
+ canViewPools: api.hasPrivilege("pools:view"),
parameters: parameters,
});
diff --git a/client/js/controls/pool_navigator_control.js b/client/js/controls/pool_navigator_control.js
new file mode 100644
index 00000000..fa4394d1
--- /dev/null
+++ b/client/js/controls/pool_navigator_control.js
@@ -0,0 +1,33 @@
+"use strict";
+
+const api = require("../api.js");
+const misc = require("../util/misc.js");
+const events = require("../events.js");
+const views = require("../util/views.js");
+
+const template = views.getTemplate("pool-navigator");
+
+class PoolNavigatorControl extends events.EventTarget {
+ constructor(hostNode, poolPostNearby) {
+ super();
+ this._hostNode = hostNode;
+ this._poolPostNearby = poolPostNearby;
+
+ views.replaceContent(
+ this._hostNode,
+ template({
+ pool: poolPostNearby.pool,
+ parameters: { query: `pool:${poolPostNearby.pool.id}` },
+ linkClass: misc.makeCssName(poolPostNearby.pool.category, "pool"),
+ canViewPosts: api.hasPrivilege("posts:view"),
+ canViewPools: api.hasPrivilege("pools:view"),
+ firstPost: poolPostNearby.firstPost,
+ previousPost: poolPostNearby.previousPost,
+ nextPost: poolPostNearby.nextPost,
+ lastPost: poolPostNearby.lastPost,
+ })
+ );
+ }
+}
+
+module.exports = PoolNavigatorControl;
\ No newline at end of file
diff --git a/client/js/controls/pool_navigator_list_control.js b/client/js/controls/pool_navigator_list_control.js
new file mode 100644
index 00000000..38ec2f12
--- /dev/null
+++ b/client/js/controls/pool_navigator_list_control.js
@@ -0,0 +1,51 @@
+"use strict";
+
+const events = require("../events.js");
+const views = require("../util/views.js");
+const PoolNavigatorControl = require("../controls/pool_navigator_control.js");
+
+const template = views.getTemplate("pool-navigator-list");
+
+class PoolNavigatorListControl extends events.EventTarget {
+ constructor(hostNode, poolPostNearby) {
+ super();
+ this._hostNode = hostNode;
+ this._poolPostNearby = poolPostNearby;
+ this._indexToNode = {};
+
+ for (let [i, entry] of this._poolPostNearby.entries()) {
+ this._installPoolNavigatorNode(entry, i);
+ }
+ }
+
+ get _poolNavigatorListNode() {
+ return this._hostNode;
+ }
+
+ _installPoolNavigatorNode(poolPostNearby, i) {
+ const poolListItemNode = document.createElement("div");
+ const poolControl = new PoolNavigatorControl(
+ poolListItemNode,
+ poolPostNearby,
+ );
+ // events.proxyEvent(commentControl, this, "submit");
+ // events.proxyEvent(commentControl, this, "score");
+ // events.proxyEvent(commentControl, this, "delete");
+ this._indexToNode[poolPostNearby.id] = poolListItemNode;
+ }
+
+ _uninstallPoolNavigatorNode(index) {
+ const poolListItemNode = this._indexToNode[index];
+ poolListItemNode.parentNode.removeChild(poolListItemNode);
+ }
+
+ _evtAdd(e) {
+ this._installPoolNavigatorNode(e.detail.index);
+ }
+
+ _evtRemove(e) {
+ this._uninstallPoolNavigatorNode(e.detail.index);
+ }
+}
+
+module.exports = PoolNavigatorListControl;
\ No newline at end of file
diff --git a/client/js/models/post_list.js b/client/js/models/post_list.js
index 8c2c9d4e..0d3655be 100644
--- a/client/js/models/post_list.js
+++ b/client/js/models/post_list.js
@@ -16,6 +16,15 @@ class PostList extends AbstractList {
);
}
+ static getNearbyPoolPosts(id) {
+ return api.get(
+ uri.formatApiLink("post", id, "pools-nearby", {
+ query: PostList._decorateSearchQuery(searchQuery || ""),
+ fields: "id",
+ })
+ );
+ }
+
static search(text, offset, limit, fields) {
return api
.get(
diff --git a/client/js/views/post_main_view.js b/client/js/views/post_main_view.js
index 5ef7f61e..88b056d4 100644
--- a/client/js/views/post_main_view.js
+++ b/client/js/views/post_main_view.js
@@ -57,6 +57,7 @@ class PostMainView {
this._installSidebar(ctx);
this._installCommentForm();
this._installComments(ctx.post.comments);
+ this._installPoolNavigators(ctx.poolPostsAround);
const showPreviousImage = () => {
if (ctx.prevPostId) {
@@ -137,6 +138,20 @@ class PostMainView {
}
}
+ _installPoolNavigators(poolPostsAround) {
+ const poolNavigatorsContainerNode = document.querySelector(
+ "#content-holder .pool-navigators-container"
+ );
+ if (!poolNavigatorsContainerNode) {
+ return;
+ }
+
+ this.poolNavigatorsControl = new PoolNavigatorListControl(
+ poolNavigatorsContainerNode,
+ poolPostsAround,
+ );
+ }
+
_installCommentForm() {
const commentFormContainer = document.querySelector(
"#content-holder .comment-form-container"