diff --git a/public_html/index.html b/public_html/index.html
index dfec08cc..c4f6e002 100644
--- a/public_html/index.html
+++ b/public_html/index.html
@@ -73,24 +73,32 @@
+
+
+
-
+
+
+
+
+
+
-
+
diff --git a/public_html/js/Presenters/PostPresenter.js b/public_html/js/Presenters/PostPresenter.js
new file mode 100644
index 00000000..2a2e13c2
--- /dev/null
+++ b/public_html/js/Presenters/PostPresenter.js
@@ -0,0 +1,57 @@
+var App = App || {};
+App.Presenters = App.Presenters || {};
+
+App.Presenters.PostPresenter = function(
+ _,
+ jQuery,
+ util,
+ promise,
+ api,
+ topNavigationPresenter,
+ messagePresenter) {
+
+ var $el = jQuery('#content');
+ var $messages = $el;
+ var template;
+ var post;
+ var postNameOrId;
+
+ function init(args, loaded) {
+ postNameOrId = args.postNameOrId;
+ topNavigationPresenter.select('posts');
+
+ promise.waitAll(
+ util.promiseTemplate('post'),
+ api.get('/posts/' + postNameOrId))
+ .then(function(
+ templatehtml,
+ response) {
+ $messages = $el.find('.messages');
+ template = _.template(templatehtml);
+
+ post = response.json;
+ topNavigationPresenter.changeTitle('@' + post.id);
+ render();
+ loaded();
+
+ }).fail(function(response) {
+ $el.empty();
+ messagePresenter.showError($messages, response.json && response.json.error || response);
+ });
+ }
+
+ function render() {
+ $el.html(template({
+ post: post,
+ formatRelativeTime: util.formatRelativeTime,
+ }));
+ }
+
+ return {
+ init: init,
+ render: render
+ };
+
+};
+
+App.DI.register('postPresenter', ['_', 'jQuery', 'util', 'promise', 'api', 'topNavigationPresenter', 'messagePresenter'], App.Presenters.PostPresenter);
diff --git a/public_html/js/Router.js b/public_html/js/Router.js
index c3a9c827..c7834e08 100644
--- a/public_html/js/Router.js
+++ b/public_html/js/Router.js
@@ -39,6 +39,7 @@ App.Router = function(pathJs, _, jQuery, util, appState, presenterManager) {
inject('#/users(/:searchArgs)', 'userListPresenter');
inject('#/user/:userName(/:tab)', 'userPresenter');
inject('#/posts(/:searchArgs)', 'postListPresenter');
+ inject('#/post(/:postNameOrId)', 'postPresenter');
inject('#/comments(/:searchArgs)', 'commentListPresenter');
inject('#/tags(/:searchArgs)', 'tagListPresenter');
inject('#/help', 'helpPresenter');
diff --git a/public_html/templates/post.tpl b/public_html/templates/post.tpl
new file mode 100644
index 00000000..cfa933dd
--- /dev/null
+++ b/public_html/templates/post.tpl
@@ -0,0 +1,30 @@
+<% var postContentUrl = '/data/posts/' + post.name %>
+
+<% if (post.contentType == 'image') { %>
+
+
+
+<% } else if (post.contentType == 'youtube') { %>
+
+
+
+<% } else if (post.contentType == 'flash') { %>
+
+
+
+<% } else if (post.contentType == 'video') { %>
+
+
+
+<% } else { console.log(new Error('Unknown post type')) } %>
diff --git a/src/Controllers/PostController.php b/src/Controllers/PostController.php
index f2ff5380..eaef7a78 100644
--- a/src/Controllers/PostController.php
+++ b/src/Controllers/PostController.php
@@ -22,8 +22,15 @@ final class PostController extends AbstractController
public function registerRoutes(\Szurubooru\Router $router)
{
- $router->get('/api/posts', [$this, 'getFiltered']);
$router->post('/api/posts', [$this, 'createPost']);
+ $router->get('/api/posts', [$this, 'getFiltered']);
+ $router->get('/api/posts/:postNameOrId', [$this, 'getByNameOrId']);
+ }
+
+ public function getByNameOrId($postNameOrId)
+ {
+ $post = $this->postService->getByNameOrId($postNameOrId);
+ return $this->postViewProxy->fromEntity($post);
}
public function getFiltered()
diff --git a/src/Services/PostService.php b/src/Services/PostService.php
index 6c24d0ef..ea198296 100644
--- a/src/Services/PostService.php
+++ b/src/Services/PostService.php
@@ -32,6 +32,20 @@ class PostService
$this->authService = $authService;
}
+ public function getByNameOrId($postNameOrId)
+ {
+ $transactionFunc = function() use ($postNameOrId)
+ {
+ $post = $this->postDao->findByName($postNameOrId);
+ if (!$post)
+ $post = $this->postDao->findById($postNameOrId);
+ if (!$post)
+ throw new \InvalidArgumentException('Post with name "' . $postName . '" was not found.');
+ return $post;
+ };
+ return $this->transactionManager->rollback($transactionFunc);
+ }
+
public function getByName($postName)
{
$transactionFunc = function() use ($postName)