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;
}