diff --git a/framework/core/js/forum/src/components/discussion-list.js b/framework/core/js/forum/src/components/discussion-list.js index deb456076..3ff7818ab 100644 --- a/framework/core/js/forum/src/components/discussion-list.js +++ b/framework/core/js/forum/src/components/discussion-list.js @@ -87,16 +87,6 @@ export default class DiscussionList extends Component { } } - delete(discussion) { - if (confirm('Are you sure you want to delete this discussion?')) { - discussion.delete(); - this.removeDiscussion(discussion); - if (app.current.discussion && app.current.discussion().id() === discussion.id()) { - app.history.back(); - } - } - } - removeDiscussion(discussion) { var index = this.discussions().indexOf(discussion); if (index !== -1) { @@ -113,7 +103,7 @@ export default class DiscussionList extends Component { var displayUnread = this.props.countType !== 'replies' && isUnread var jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1) - var controls = this.controlItems(discussion).toArray(); + var controls = discussion.controls(this).toArray(); var discussionRoute = app.route('discussion', { id: discussion.id(), slug: discussion.slug() }); var active = m.route().substr(0, discussionRoute.length) === discussionRoute; @@ -175,23 +165,4 @@ export default class DiscussionList extends Component { return items; } - - /** - Build an item list of controls for a discussion listing. - - @return {ItemList} - */ - controlItems(discussion) { - var items = new ItemList(); - - if (discussion.canDelete()) { - items.add('delete', ActionButton.component({ - icon: 'times', - label: 'Delete', - onclick: this.delete.bind(this, discussion) - })); - } - - return items; - } } diff --git a/framework/core/js/forum/src/components/discussion-page.js b/framework/core/js/forum/src/components/discussion-page.js index b98384a34..f031074d3 100644 --- a/framework/core/js/forum/src/components/discussion-page.js +++ b/framework/core/js/forum/src/components/discussion-page.js @@ -171,7 +171,7 @@ export default class DiscussionPage extends Component { items.add('controls', DropdownSplit.component({ - items: this.controlItems().toArray(), + items: this.discussion().controls(this).toArray(), icon: 'reply', buttonClass: 'btn btn-primary', wrapperClass: 'primary-control' @@ -188,68 +188,6 @@ export default class DiscussionPage extends Component { return items; } - /** - - */ - controlItems() { - var items = new ItemList(); - var discussion = this.discussion(); - - items.add('reply', ActionButton.component({ icon: 'reply', label: 'Reply', onclick: this.reply.bind(this) })); - - items.add('separator', Separator.component()); - - if (discussion.canEdit()) { - items.add('rename', ActionButton.component({ icon: 'pencil', label: 'Rename', onclick: this.rename.bind(this) })); - } - - if (discussion.canDelete()) { - items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete', onclick: this.delete.bind(this) })); - } - - return items; - } - - reply() { - if (app.session.user()) { - this.streamContent.goToLast(); - - if (!this.composer || app.composer.component !== this.composer) { - this.composer = new ComposerReply({ - user: app.session.user(), - discussion: this.discussion() - }); - app.composer.load(this.composer); - } - app.composer.show(); - } else { - // signup - } - } - - delete() { - if (confirm('Are you sure you want to delete this discussion?')) { - var discussion = this.discussion(); - discussion.delete(); - if (app.cache.discussionList) { - app.cache.discussionList.removeDiscussion(discussion); - } - app.history.back(); - } - } - - rename() { - var discussion = this.discussion(); - var currentTitle = discussion.title(); - var title = prompt('Enter a new title for this discussion:', currentTitle); - if (title && title !== currentTitle) { - discussion.save({title}).then(discussion => { - discussion.addedPosts().forEach(post => this.stream().addPostToEnd(post)); - m.redraw(); - }); - } - } - /** */ diff --git a/framework/core/js/lib/models/discussion.js b/framework/core/js/lib/models/discussion.js index 5aae82450..41c752f30 100644 --- a/framework/core/js/lib/models/discussion.js +++ b/framework/core/js/lib/models/discussion.js @@ -1,8 +1,84 @@ import Model from 'flarum/model'; import computed from 'flarum/utils/computed'; import ItemList from 'flarum/utils/item-list'; +import DiscussionPage from 'flarum/components/discussion-page'; +import ActionButton from 'flarum/components/action-button'; +import Separator from 'flarum/components/separator'; +import ComposerReply from 'flarum/components/composer-reply'; -class Discussion extends Model {} +class Discussion extends Model { + unreadCount() { + var user = app.session.user(); + if (user && user.readTime() < this.lastTime()) { + return Math.max(0, this.lastPostNumber() - (this.readNumber() || 0)) + } + return 0; + } + + badges() { + return new ItemList(); + } + + controls(context) { + var items = new ItemList(); + + if (context instanceof DiscussionPage) { + items.add('reply', ActionButton.component({ icon: 'reply', label: 'Reply', onclick: this.replyAction.bind(this) })); + + items.add('separator', Separator.component()); + } + + if (this.canEdit()) { + items.add('rename', ActionButton.component({ icon: 'pencil', label: 'Rename', onclick: this.renameAction.bind(this) })); + } + + if (this.canDelete()) { + items.add('delete', ActionButton.component({ icon: 'times', label: 'Delete', onclick: this.deleteAction.bind(this) })); + } + + return items; + } + + replyAction() { + if (app.session.user()) { + if (app.current.discussion && app.current.discussion().id() === this.id()) { + app.current.streamContent.goToLast(); + } + app.composer.load(new ComposerReply({ + user: app.session.user(), + discussion: this + })); + app.composer.show(); + } else { + // signup + } + } + + deleteAction() { + if (confirm('Are you sure you want to delete this discussion?')) { + this.delete(); + if (app.cache.discussionList) { + app.cache.discussionList.removeDiscussion(this); + } + if (app.current.discussion && app.current.discussion().id() === this.id()) { + app.history.back(); + } + } + } + + renameAction() { + var currentTitle = this.title(); + var title = prompt('Enter a new title for this discussion:', currentTitle); + if (title && title !== currentTitle) { + this.save({title}).then(discussion => { + if (app.current.discussion && app.current.discussion().id() === discussion.id()) { + discussion.addedPosts().forEach(post => app.current.stream().addPostToEnd(post)); + } + m.redraw(); + }); + } + } +} Discussion.prototype.id = Model.prop('id'); Discussion.prototype.title = Model.prop('title'); @@ -27,19 +103,11 @@ Discussion.prototype.repliesCount = computed('commentsCount', commentsCount => c Discussion.prototype.posts = Model.many('posts'); Discussion.prototype.relevantPosts = Model.many('relevantPosts'); Discussion.prototype.addedPosts = Model.many('addedPosts'); +Discussion.prototype.removedPosts = Model.prop('removedPosts'); Discussion.prototype.readTime = Model.prop('readTime', Model.date); Discussion.prototype.readNumber = Model.prop('readNumber'); -Discussion.prototype.unreadCount = function() { - var user = app.session.user(); - if (user && user.readTime() < this.lastTime()) { - return Math.max(0, this.lastPostNumber() - (this.readNumber() || 0)) - } - return 0 -}; Discussion.prototype.isUnread = computed('unreadCount', unreadCount => !!unreadCount); -Discussion.prototype.badges = () => new ItemList(); - export default Discussion;