diff --git a/app/assets/javascripts/deprecated.js b/app/assets/javascripts/deprecated.js index ee6592848ae..151ed975d0c 100644 --- a/app/assets/javascripts/deprecated.js +++ b/app/assets/javascripts/deprecated.js @@ -1,31 +1,7 @@ (function() { var Discourse = require('discourse').default; - function deprecate(module, methods) { - var result = {}; - - methods.forEach(function(m) { - result[m] = function() { - Ember.warn("Discourse." + module + "." + m + " is deprecated. Export a setup() function instead"); - }; - }); - - Discourse[module] = result; - } - - deprecate('Markdown', ['whiteListTag', 'whiteListIframe']); - deprecate('Dialect', ['inlineRegexp', 'inlineBetween', 'addPreProcessor', 'replaceBlock', - 'inlineReplace', 'registerInline', 'registerEmoji']); - - deprecate('BBCode', ['replaceBBCode', 'register', 'rawBBCode', 'replaceBBCodeParamsRaw']); - Discourse.dialect_deprecated = true; - Discourse.ajax = function() { - var ajax = require('discourse/lib/ajax').ajax; - Ember.warn("Discourse.ajax is deprecated. Import the module and use it instead"); - return ajax.apply(this, arguments); - }; - window.Discourse = Discourse; })(); diff --git a/app/assets/javascripts/discourse.js.es6 b/app/assets/javascripts/discourse.js.es6 index 523b0ee2255..cbbc0bf9cfe 100644 --- a/app/assets/javascripts/discourse.js.es6 +++ b/app/assets/javascripts/discourse.js.es6 @@ -135,15 +135,6 @@ const Discourse = Ember.Application.extend({ } }); }); - - const utils = require('discourse/lib/utilities'); - Discourse.Utilities = {}; - Object.keys(utils).forEach(function(k) { - Discourse.Utilities[k] = function() { - Ember.warn('Discourse.Utilities is deprecated. Import it as a module'); - return utils[k].apply(utils, arguments); - }; - }); }, @computed('currentAssetVersion', 'desiredAssetVersion') diff --git a/app/assets/javascripts/discourse/components/d-button.js.es6 b/app/assets/javascripts/discourse/components/d-button.js.es6 index c2d7bf1f310..bd606facafd 100644 --- a/app/assets/javascripts/discourse/components/d-button.js.es6 +++ b/app/assets/javascripts/discourse/components/d-button.js.es6 @@ -1,6 +1,9 @@ import { default as computed } from 'ember-addons/ember-computed-decorators'; export default Ember.Component.extend({ + // subclasses need this + layoutName: 'components/d-button', + tagName: 'button', classNameBindings: [':btn', 'noText'], attributeBindings: ['disabled', 'translatedTitle:title'], diff --git a/app/assets/javascripts/discourse/components/login-reply-button.js.es6 b/app/assets/javascripts/discourse/components/login-reply-button.js.es6 new file mode 100644 index 00000000000..e162faf2673 --- /dev/null +++ b/app/assets/javascripts/discourse/components/login-reply-button.js.es6 @@ -0,0 +1,7 @@ +import Button from 'discourse/components/d-button'; + +export default Button.extend({ + label: 'topic.reply.title', + icon: 'reply', + action: 'showLogin' +}); diff --git a/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 b/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 index 1b41ae04dc2..d9aad34dccf 100644 --- a/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-footer-buttons.js.es6 @@ -1,23 +1,52 @@ -import ContainerView from 'discourse/views/container'; +import computed from 'ember-addons/ember-computed-decorators'; -export default ContainerView.extend({ +export default Ember.Component.extend({ elementId: 'topic-footer-buttons', + // Allow us to extend it + layoutName: 'components/topic-footer-buttons', + init() { this._super(); - if (this.currentUser) { - const viewArgs = this.getProperties('topic', 'topicDelegated'); - viewArgs.currentUser = this.currentUser; + this._actions = this._actions || {}; - this.attachViewWithArgs(viewArgs, 'topic-footer-main-buttons'); - this.attachViewWithArgs(viewArgs, 'pinned-button'); - this.attachViewWithArgs(viewArgs, 'topic-notifications-button'); + (this.get('topicDelegated') || []).forEach(m => { + this._actions[m] = function() { + this.sendAction(m); + }; + this.set(m, m); + }); + }, + + @computed('topic.details.can_invite_to') + canInviteTo(result) { + return !this.site.mobileView && result; + }, + + inviteDisabled: Ember.computed.or('topic.archived', 'topic.closed', 'topic.deleted'), + + @computed + showAdminButton() { + return !this.site.mobileView && this.currentUser.get('canManageTopic'); + }, + + @computed('topic.message_archived') + archiveIcon: archived => archived ? '' : 'folder', + + @computed('topic.message_archived') + archiveTitle: archived => archived ? 'topic.move_to_inbox.help' : 'topic.archive_message.help', + + @computed('topic.message_archived') + archiveLabel: archived => archived ? "topic.move_to_inbox.title" : "topic.archive_message.title", + + @computed('topic.bookmarked') + bookmarkClass: bookmarked => bookmarked ? 'bookmark bookmarked' : 'bookmark', + + @computed('topic.bookmarked') + bookmarkLabel: bookmarked => bookmarked ? 'bookmarked.clear_bookmarks' : 'bookmarked.title', + + @computed('topic.bookmarked') + bookmarkTitle: bookmarked => bookmarked ? "bookmarked.help.unbookmark" : "bookmarked.help.bookmark", - this.trigger('additionalButtons', this); - } else { - // If not logged in give them a login control - this.attachViewClass('login-reply-button'); - } - } }); diff --git a/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6 b/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6 index 8796a7bc141..3ed113419e5 100644 --- a/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-footer-mobile-dropdown.js.es6 @@ -59,7 +59,7 @@ export default Combobox.extend({ refresh(); break; case 'flag': - controller.send('showFlagTopic', topic); + controller.send('showFlagTopic'); refresh(); break; } diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 7d678a57fc5..8761c6c9a2b 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -45,7 +45,11 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { 'jumpToPost', 'jumpToIndex', 'jumpBottom', - 'replyToPost' + 'replyToPost', + 'toggleArchiveMessage', + 'showInvite', + 'toggleBookmark', + 'showFlagTopic' ], _titleChanged: function() { @@ -269,18 +273,20 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { this.deleteTopic(); }, - archiveMessage() { + // Archive a PM (as opposed to archiving a topic) + toggleArchiveMessage() { const topic = this.get('model'); - topic.archiveMessage().then(()=>{ - this.gotoInbox(topic.get("inboxGroupName")); - }); - }, + if (topic.get('archiving')) { return; } - moveToInbox() { - const topic = this.get('model'); - topic.moveToInbox().then(()=>{ - this.gotoInbox(topic.get("inboxGroupName")); - }); + if (topic.get('message_archived')) { + topic.moveToInbox().then(()=>{ + this.gotoInbox(topic.get("inboxGroupName")); + }); + } else { + topic.archiveMessage().then(()=>{ + this.gotoInbox(topic.get("inboxGroupName")); + }); + } }, // Post related methods diff --git a/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 b/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 index f38e4b92b85..5e3de23fee3 100644 --- a/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 +++ b/app/assets/javascripts/discourse/pre-initializers/inject-discourse-objects.js.es6 @@ -7,7 +7,6 @@ import DiscourseLocation from 'discourse/lib/discourse-location'; import SearchService from 'discourse/services/search'; import { startTracking, default as TopicTrackingState } from 'discourse/models/topic-tracking-state'; import ScreenTrack from 'discourse/lib/screen-track'; -import TopicFooterButtons from 'discourse/components/topic-footer-buttons'; function inject() { const app = arguments[0], @@ -73,13 +72,6 @@ export default { app.register('key-value-store:main', keyValueStore, { instantiate: false }); injectAll(app, 'keyValueStore'); - Discourse.TopicFooterButtonsView = { - reopen(obj) { - Ember.warn('`Discourse.TopicFooterButtonsView` is deprecated. Use the `topic-footer-buttons` component instead'); - TopicFooterButtons.reopen(obj); - } - }; - startTracking(topicTrackingState); } }; diff --git a/app/assets/javascripts/discourse/routes/topic.js.es6 b/app/assets/javascripts/discourse/routes/topic.js.es6 index a31736bc158..0ee442dde5b 100644 --- a/app/assets/javascripts/discourse/routes/topic.js.es6 +++ b/app/assets/javascripts/discourse/routes/topic.js.es6 @@ -45,7 +45,8 @@ const TopicRoute = Discourse.Route.extend({ this.controllerFor('flag').setProperties({ selected: null, flagTopic: false }); }, - showFlagTopic(model) { + showFlagTopic() { + const model = this.modelFor('topic'); showModal('flag', { model }); this.controllerFor('flag').setProperties({ selected: null, flagTopic: true }); }, diff --git a/app/assets/javascripts/discourse/templates/components/d-button.hbs b/app/assets/javascripts/discourse/templates/components/d-button.hbs index f0e5f1d6b6b..47b714b8dc1 100644 --- a/app/assets/javascripts/discourse/templates/components/d-button.hbs +++ b/app/assets/javascripts/discourse/templates/components/d-button.hbs @@ -1,3 +1,6 @@ -{{fa-icon icon}} +{{#if icon}} + {{fa-icon icon}} +{{/if}} + {{{translatedLabel}}} {{yield}} diff --git a/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs b/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs new file mode 100644 index 00000000000..518abc95c28 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/topic-footer-buttons.hbs @@ -0,0 +1,60 @@ +{{#if showAdminButton}} + {{topic-admin-menu-button topic=topic delegated=topicDelegated openUpwards="true"}} +{{/if}} + +{{#unless topic.isPrivateMessage}} + {{#if site.mobileView}} + {{topic-footer-mobile-dropdown topic=topic}} + {{else}} + {{d-button class=bookmarkClass + title=bookmarkTitle + label=bookmarkLabel + icon="bookmark" + action="toggleBookmark"}} + + + + {{#if topic.details.can_flag_topic}} + {{d-button class="flag-topic" + title="topic.flag_topic.help" + label="topic.flag_topic.title" + icon="flag" + action="showFlagTopic"}} + {{/if}} + + {{/if}} +{{/unless}} + +{{#if canInviteTo}} + {{d-button class="invite-topic" + title="topic.invite_reply.help" + label="topic.invite_reply.title" + icon="users" + action="showInvite" + disabled=inviteDisabled}} +{{/if}} + +{{#if topic.isPrivateMessage}} + {{d-button class="standard" + title=archiveTitle + label=archiveLabel + icon=archiveIcon + action="toggleArchiveMessage"}} +{{/if}} + +{{#if topic.details.can_create_post}} + {{d-button class="btn-primary create" + icon="reply" + action="replyToPost" + label="topic.reply.title" + title="topic.reply.help"}} +{{/if}} + +{{plugin-outlet "after-topic-footer-main-buttons" tagName="span"}} + +{{pinned-button topic=topic topicDelegated=topicDelegated}} +{{topic-notifications-button topic=topic topicDelegated=topicDelegated}} +{{plugin-outlet "after-topic-footer-buttons" tagName="span"}} diff --git a/app/assets/javascripts/discourse/templates/topic.hbs b/app/assets/javascripts/discourse/templates/topic.hbs index f54fecc8855..5c6689f0d6e 100644 --- a/app/assets/javascripts/discourse/templates/topic.hbs +++ b/app/assets/javascripts/discourse/templates/topic.hbs @@ -147,7 +147,11 @@ {{! replace "Log In to Reply" with the infobox }} {{signup-cta}} {{else}} - {{topic-footer-buttons topic=model topicDelegated=topicDelegated}} + {{#if currentUser}} + {{topic-footer-buttons topic=model topicDelegated=topicDelegated}} + {{else}} + {{d-button icon="reply" class="btn-primary" action="showLogin" label="topic.reply.title"}} + {{/if}} {{/if}} {{#if model.pending_posts_count}} diff --git a/app/assets/javascripts/discourse/views/archive-button.js.es6 b/app/assets/javascripts/discourse/views/archive-button.js.es6 deleted file mode 100644 index 278a1c0c200..00000000000 --- a/app/assets/javascripts/discourse/views/archive-button.js.es6 +++ /dev/null @@ -1,35 +0,0 @@ -import { bufferedRender } from 'discourse-common/lib/buffered-render'; - -export default Ember.View.extend(bufferedRender({ - tagName: 'button', - classNames: ['btn', 'standard'], - attributeBindings: ['title'], - archived: Em.computed.alias('controller.model.message_archived'), - archiving: Em.computed.alias('controller.model.archiving'), - rerenderTriggers: ['archived', 'archiving'], - - title: function() { - const key = this.get('archived') ? 'topic.move_to_inbox.help' : 'topic.archive_message.help'; - return I18n.t(key); - }.property('archived'), - - buildBuffer(buffer) { - if (this.get('archived')){ - buffer.push(I18n.t('topic.move_to_inbox.title')); - } else { - buffer.push(""); - buffer.push(I18n.t('topic.archive_message.title')); - } - }, - - click() { - if (!this.get('archiving')) { - if (this.get('archived')) { - this.get('controller').send('moveToInbox'); - } else { - this.get('controller').send('archiveMessage'); - } - } - } -})); - diff --git a/app/assets/javascripts/discourse/views/bookmark-button.js.es6 b/app/assets/javascripts/discourse/views/bookmark-button.js.es6 deleted file mode 100644 index 200874b6bb8..00000000000 --- a/app/assets/javascripts/discourse/views/bookmark-button.js.es6 +++ /dev/null @@ -1,28 +0,0 @@ -import ButtonView from 'discourse/views/button'; -import { iconHTML } from 'discourse-common/helpers/fa-icon'; - -export default ButtonView.extend({ - classNames: ['bookmark'], - attributeBindings: ['disabled'], - - bookmarked: Ember.computed.alias('controller.model.bookmarked'), - - textKey: function() { - return this.get('bookmarked') ? 'bookmarked.clear_bookmarks' : 'bookmarked.title'; - }.property('bookmarked'), - - rerenderTriggers: ['bookmarked'], - - helpKey: function() { - return this.get("bookmarked") ? "bookmarked.help.unbookmark" : "bookmarked.help.bookmark"; - }.property("bookmarked"), - - click() { - this.get('controller').send('toggleBookmark'); - }, - - renderIcon(buffer) { - const className = this.get("bookmarked") ? "bookmarked" : ""; - buffer.push(iconHTML('bookmark', { class: className })); - } -}); diff --git a/app/assets/javascripts/discourse/views/flag-topic-button.js.es6 b/app/assets/javascripts/discourse/views/flag-topic-button.js.es6 deleted file mode 100644 index da32165cb68..00000000000 --- a/app/assets/javascripts/discourse/views/flag-topic-button.js.es6 +++ /dev/null @@ -1,16 +0,0 @@ -import ButtonView from 'discourse/views/button'; -import { iconHTML } from 'discourse-common/helpers/fa-icon'; - -export default ButtonView.extend({ - classNames: ['flag-topic'], - textKey: 'topic.flag_topic.title', - helpKey: 'topic.flag_topic.help', - - click() { - this.get('controller').send('showFlagTopic', this.get('controller.content')); - }, - - renderIcon(buffer) { - buffer.push(iconHTML('flag')); - } -}); diff --git a/app/assets/javascripts/discourse/views/invite-reply-button.js.es6 b/app/assets/javascripts/discourse/views/invite-reply-button.js.es6 deleted file mode 100644 index ba450494fd2..00000000000 --- a/app/assets/javascripts/discourse/views/invite-reply-button.js.es6 +++ /dev/null @@ -1,18 +0,0 @@ -import ButtonView from 'discourse/views/button'; -import { iconHTML } from 'discourse-common/helpers/fa-icon'; - -export default ButtonView.extend({ - classNames: ['invite-topic'], - textKey: 'topic.invite_reply.title', - helpKey: 'topic.invite_reply.help', - attributeBindings: ['disabled'], - disabled: Em.computed.or('controller.model.archived', 'controller.model.closed', 'controller.model.deleted'), - - renderIcon(buffer) { - buffer.push(iconHTML('users')); - }, - - click() { - this.get('controller').send('showInvite'); - } -}); diff --git a/app/assets/javascripts/discourse/views/login-reply-button.js.es6 b/app/assets/javascripts/discourse/views/login-reply-button.js.es6 deleted file mode 100644 index 42dbba0cd2f..00000000000 --- a/app/assets/javascripts/discourse/views/login-reply-button.js.es6 +++ /dev/null @@ -1,12 +0,0 @@ -import ButtonView from 'discourse/views/button'; - -export default ButtonView.extend({ - textKey: 'topic.reply.title', - classNames: ['btn', 'btn-primary', 'create'], - click: function() { - this.get('controller').send('showLogin'); - }, - renderIcon: function(buffer) { - buffer.push(""); - } -}); diff --git a/app/assets/javascripts/discourse/views/reply-button.js.es6 b/app/assets/javascripts/discourse/views/reply-button.js.es6 deleted file mode 100644 index 876b417ec65..00000000000 --- a/app/assets/javascripts/discourse/views/reply-button.js.es6 +++ /dev/null @@ -1,23 +0,0 @@ -import ButtonView from 'discourse/views/button'; - -export default ButtonView.extend({ - classNames: ['btn', 'btn-primary', 'create'], - helpKey: 'topic.reply.help', - - text: function() { - var archetypeCapitalized = this.get('controller.content.archetype').capitalize(); - var customTitle = this.get("parentView.replyButtonText" + archetypeCapitalized); - if (customTitle) { return customTitle; } - - return I18n.t("topic.reply.title"); - }.property(), - - renderIcon: function(buffer) { - buffer.push(""); - }, - - click: function() { - this.get('controller').send('replyToPost'); - } -}); - diff --git a/app/assets/javascripts/discourse/views/share-button.js.es6 b/app/assets/javascripts/discourse/views/share-button.js.es6 deleted file mode 100644 index cac2134277b..00000000000 --- a/app/assets/javascripts/discourse/views/share-button.js.es6 +++ /dev/null @@ -1,14 +0,0 @@ -import ButtonView from 'discourse/views/button'; -import { iconHTML } from 'discourse-common/helpers/fa-icon'; - -export default ButtonView.extend({ - classNames: ['share'], - textKey: 'topic.share.title', - helpKey: 'topic.share.help', - 'data-share-url': Em.computed.alias('topic.shareUrl'), - topic: Em.computed.alias('controller.model'), - - renderIcon(buffer) { - buffer.push(iconHTML("link")); - } -}); diff --git a/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 b/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 index b28b1e9c34c..4ece5f553fe 100644 --- a/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 +++ b/app/assets/javascripts/discourse/views/topic-footer-main-buttons.js.es6 @@ -1,45 +1,2 @@ -import ContainerView from 'discourse/views/container'; -import { on } from 'ember-addons/ember-computed-decorators'; - -export default ContainerView.extend({ - elementId: 'topic-footer-main-buttons', - - @on('init') - createButtons() { - const mobileView = this.site.mobileView; - - const topic = this.get('topic'); - - if (!mobileView && this.currentUser.get('canManageTopic')) { - const viewArgs = { topic, delegated: this.get('topicDelegated'), openUpwards: true }; - this.attachViewWithArgs(viewArgs, 'topic-admin-menu-button'); - } - - if (!topic.get('isPrivateMessage')) { - if (mobileView) { - this.attachViewWithArgs({ topic }, 'topic-footer-mobile-dropdown'); - } else { - // We hide some controls from private messages - this.attachViewClass('bookmark-button'); - this.attachViewClass('share-button'); - if (this.get('topic.details.can_flag_topic')) { - this.attachViewClass('flag-topic-button'); - } - } - } - - if (!mobileView && this.get('topic.details.can_invite_to')) { - this.attachViewClass('invite-reply-button'); - } - - if (topic.get('isPrivateMessage')) { - this.attachViewClass('archive-button'); - } - - if (this.get('topic.details.can_create_post')) { - this.attachViewClass('reply-button'); - } - - this.trigger('additionalButtons', this); - } -}); +// In case plugins are using the old `additionalButtons` API, don't break +export default Ember.View.extend(); diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss index 5014af1a803..a53b90f9ba6 100644 --- a/app/assets/stylesheets/desktop/topic-post.scss +++ b/app/assets/stylesheets/desktop/topic-post.scss @@ -436,6 +436,11 @@ a.star { margin-right: 10px; .fa-bookmark.bookmarked { color: $tertiary; } } + + .bookmark.bookmarked .fa-bookmark { + color: $tertiary; + } + .notification-options p { display: inline-block; }