diff options
| author | rr- <rr-@sakuya.pl> | 2016-10-22 10:03:38 +0200 |
|---|---|---|
| committer | rr- <rr-@sakuya.pl> | 2016-10-22 14:05:56 +0200 |
| commit | f1445b9c24b286a9f74a2fead655ab5c169bc74b (patch) | |
| tree | eba026eb8dcd53f8d4db58e9dc50af1b857d92ed /client/js/controllers/post_main_controller.js | |
| parent | 8c0fa7f49ea24606e1887b76e89c2bfd155b1776 (diff) | |
client/posts: add post merging
Diffstat (limited to 'client/js/controllers/post_main_controller.js')
| -rw-r--r-- | client/js/controllers/post_main_controller.js | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/client/js/controllers/post_main_controller.js b/client/js/controllers/post_main_controller.js new file mode 100644 index 0000000..561ecb4 --- /dev/null +++ b/client/js/controllers/post_main_controller.js @@ -0,0 +1,276 @@ +'use strict'; + +const router = require('../router.js'); +const api = require('../api.js'); +const misc = require('../util/misc.js'); +const settings = require('../models/settings.js'); +const Comment = require('../models/comment.js'); +const Post = require('../models/post.js'); +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'); + +class PostMainController extends BasePostController { + constructor(ctx, editMode) { + super(ctx); + + let parameters = ctx.parameters; + Promise.all([ + Post.get(ctx.parameters.id), + PostList.getAround( + ctx.parameters.id, this._decorateSearchQuery( + parameters ? parameters.query : '')), + ]).then(responses => { + const [post, aroundResponse] = responses; + + // remove junk from query, but save it into history so that it can + // be still accessed after history navigation / page refresh + if (parameters.query) { + ctx.state.parameters = parameters; + const url = editMode ? + '/post/' + ctx.parameters.id + '/edit' : + '/post/' + ctx.parameters.id; + router.replace(url, ctx.state, false); + } + + this._post = post; + this._view = new PostMainView({ + post: post, + editMode: editMode, + prevPostId: aroundResponse.prev ? aroundResponse.prev.id : null, + nextPostId: aroundResponse.next ? aroundResponse.next.id : null, + canEditPosts: api.hasPrivilege('posts:edit'), + canDeletePosts: api.hasPrivilege('posts:delete'), + canFeaturePosts: api.hasPrivilege('posts:feature'), + canListComments: api.hasPrivilege('comments:list'), + canCreateComments: api.hasPrivilege('comments:create'), + parameters: parameters, + }); + + if (this._view.sidebarControl) { + this._view.sidebarControl.addEventListener( + 'favorite', e => this._evtFavoritePost(e)); + this._view.sidebarControl.addEventListener( + 'unfavorite', e => this._evtUnfavoritePost(e)); + this._view.sidebarControl.addEventListener( + 'score', e => this._evtScorePost(e)); + this._view.sidebarControl.addEventListener( + 'fitModeChange', e => this._evtFitModeChange(e)); + this._view.sidebarControl.addEventListener( + 'change', e => this._evtPostChange(e)); + this._view.sidebarControl.addEventListener( + 'submit', e => this._evtUpdatePost(e)); + this._view.sidebarControl.addEventListener( + 'feature', e => this._evtFeaturePost(e)); + this._view.sidebarControl.addEventListener( + 'delete', e => this._evtDeletePost(e)); + this._view.sidebarControl.addEventListener( + 'merge', e => this._evtMergePost(e)); + } + + if (this._view.commentFormControl) { + this._view.commentFormControl.addEventListener( + 'change', e => this._evtCommentChange(e)); + this._view.commentFormControl.addEventListener( + 'submit', e => this._evtCreateComment(e)); + } + + if (this._view.commentListControl) { + this._view.commentListControl.addEventListener( + 'submit', e => this._evtUpdateComment(e)); + this._view.commentListControl.addEventListener( + 'score', e => this._evtScoreComment(e)); + this._view.commentListControl.addEventListener( + 'delete', e => this._evtDeleteComment(e)); + } + }, errorMessage => { + this._view = new EmptyView(); + this._view.showError(errorMessage); + }); + } + + _decorateSearchQuery(text) { + const browsingSettings = settings.get(); + let disabledSafety = []; + for (let key of Object.keys(browsingSettings.listPosts)) { + if (browsingSettings.listPosts[key] === false) { + disabledSafety.push(key); + } + } + if (disabledSafety.length) { + text = `-rating:${disabledSafety.join(',')} ${text}`; + } + return text.trim(); + } + + _evtFitModeChange(e) { + const browsingSettings = settings.get(); + browsingSettings.fitMode = e.detail.mode; + settings.save(browsingSettings); + } + + _evtFeaturePost(e) { + this._view.sidebarControl.disableForm(); + this._view.sidebarControl.clearMessages(); + e.detail.post.feature() + .then(() => { + this._view.sidebarControl.showSuccess('Post featured.'); + this._view.sidebarControl.enableForm(); + }, errorMessage => { + this._view.sidebarControl.showError(errorMessage); + this._view.sidebarControl.enableForm(); + }); + } + + _evtMergePost(e) { + router.show('/post/' + e.detail.post.id + '/merge'); + } + + _evtDeletePost(e) { + this._view.sidebarControl.disableForm(); + this._view.sidebarControl.clearMessages(); + e.detail.post.delete() + .then(() => { + misc.disableExitConfirmation(); + const ctx = router.show('/posts'); + ctx.controller.showSuccess('Post deleted.'); + }, errorMessage => { + this._view.sidebarControl.showError(errorMessage); + this._view.sidebarControl.enableForm(); + }); + } + + _evtUpdatePost(e) { + this._view.sidebarControl.disableForm(); + this._view.sidebarControl.clearMessages(); + const post = e.detail.post; + if (e.detail.tags !== undefined) { + post.tags = e.detail.tags; + } + if (e.detail.safety !== undefined) { + post.safety = e.detail.safety; + } + if (e.detail.flags !== undefined) { + post.flags = e.detail.flags; + } + if (e.detail.relations !== undefined) { + post.relations = e.detail.relations; + } + if (e.detail.content !== undefined) { + post.newContent = e.detail.content; + } + if (e.detail.thumbnail !== undefined) { + post.newThumbnail = e.detail.thumbnail; + } + post.save() + .then(() => { + this._view.sidebarControl.showSuccess('Post saved.'); + this._view.sidebarControl.enableForm(); + misc.disableExitConfirmation(); + }, errorMessage => { + this._view.sidebarControl.showError(errorMessage); + this._view.sidebarControl.enableForm(); + }); + } + + _evtPostChange(e) { + misc.enableExitConfirmation(); + } + + _evtCommentChange(e) { + misc.enableExitConfirmation(); + } + + _evtCreateComment(e) { + // TODO: disable form + const comment = Comment.create(this._post.id); + comment.text = e.detail.text; + comment.save() + .then(() => { + this._post.comments.add(comment); + this._view.commentFormControl.setText(''); + // TODO: enable form + misc.disableExitConfirmation(); + }, errorMessage => { + this._view.commentFormControl.showError(errorMessage); + // TODO: enable form + }); + } + + _evtUpdateComment(e) { + // TODO: disable form + e.detail.comment.text = e.detail.text; + e.detail.comment.save() + .catch(errorMessage => { + e.detail.target.showError(errorMessage); + // TODO: enable form + }); + } + + _evtScoreComment(e) { + e.detail.comment.setScore(e.detail.score) + .catch(errorMessage => { + window.alert(errorMessage); + }); + } + + _evtDeleteComment(e) { + e.detail.comment.delete() + .catch(errorMessage => { + window.alert(errorMessage); + }); + } + + _evtScorePost(e) { + if (!api.hasPrivilege('posts:score')) { + return; + } + e.detail.post.setScore(e.detail.score) + .catch(errorMessage => { + window.alert(errorMessage); + }); + } + + _evtFavoritePost(e) { + if (!api.hasPrivilege('posts:favorite')) { + return; + } + e.detail.post.addToFavorites() + .catch(errorMessage => { + window.alert(errorMessage); + }); + } + + _evtUnfavoritePost(e) { + if (!api.hasPrivilege('posts:favorite')) { + return; + } + e.detail.post.removeFromFavorites() + .catch(errorMessage => { + window.alert(errorMessage); + }); + } +} + +module.exports = router => { + router.enter('/post/:id/edit/:parameters(.*)?', + (ctx, next) => { misc.parseUrlParametersRoute(ctx, next); }, + (ctx, next) => { + // restore parameters from history state + if (ctx.state.parameters) { + Object.assign(ctx.parameters, ctx.state.parameters); + } + ctx.controller = new PostMainController(ctx, true); + }); + router.enter( + '/post/:id/:parameters(.*)?', + (ctx, next) => { misc.parseUrlParametersRoute(ctx, next); }, + (ctx, next) => { + // restore parameters from history state + if (ctx.state.parameters) { + Object.assign(ctx.parameters, ctx.state.parameters); + } + ctx.controller = new PostMainController(ctx, false); + }); +}; |