From 8b87d8ac2d043b494baab39538013e54b343efd2 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Tue, 13 Jan 2015 17:26:05 -0500 Subject: [PATCH] Refactor sharing dialog for extensibility --- .../discourse/components/share-source.js.es6 | 9 ++ .../discourse/controllers/share.js.es6 | 28 +++---- .../initializers/sharing-sources.js.es6 | 52 ++++++++++++ .../javascripts/discourse/lib/sharing.js.es6 | 40 +++++++++ .../discourse/models/share_link.js | 84 ------------------- .../templates/components/share-source.hbs | 1 + .../javascripts/discourse/templates/share.hbs | 31 +++---- .../discourse/templates/share_link.hbs | 5 -- .../discourse/views/share-link.js.es6 | 5 -- .../javascripts/discourse/views/share.js.es6 | 8 -- app/assets/javascripts/main_include.js | 1 + 11 files changed, 133 insertions(+), 131 deletions(-) create mode 100644 app/assets/javascripts/discourse/components/share-source.js.es6 create mode 100644 app/assets/javascripts/discourse/initializers/sharing-sources.js.es6 create mode 100644 app/assets/javascripts/discourse/lib/sharing.js.es6 delete mode 100644 app/assets/javascripts/discourse/models/share_link.js create mode 100644 app/assets/javascripts/discourse/templates/components/share-source.hbs delete mode 100644 app/assets/javascripts/discourse/templates/share_link.hbs delete mode 100644 app/assets/javascripts/discourse/views/share-link.js.es6 diff --git a/app/assets/javascripts/discourse/components/share-source.js.es6 b/app/assets/javascripts/discourse/components/share-source.js.es6 new file mode 100644 index 00000000000..03afa841430 --- /dev/null +++ b/app/assets/javascripts/discourse/components/share-source.js.es6 @@ -0,0 +1,9 @@ +export default Ember.Component.extend({ + classNameBindings: [':social-link'], + + actions: { + share: function(source) { + this.sendAction('action', source); + }, + } +}); diff --git a/app/assets/javascripts/discourse/controllers/share.js.es6 b/app/assets/javascripts/discourse/controllers/share.js.es6 index fa8103005b4..975f591fa9a 100644 --- a/app/assets/javascripts/discourse/controllers/share.js.es6 +++ b/app/assets/javascripts/discourse/controllers/share.js.es6 @@ -1,7 +1,8 @@ -import DiscourseController from 'discourse/controllers/controller'; +import Sharing from 'discourse/lib/sharing'; -export default DiscourseController.extend({ +export default Ember.Controller.extend({ needs: ['topic'], + title: Ember.computed.alias('controllers.topic.title'), displayDate: function() { return Discourse.Formatter.longDateNoYear(new Date(this.get('date'))); @@ -14,20 +15,17 @@ export default DiscourseController.extend({ return false; }, - sharePopup: function(target, url) { - window.open(url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=600,height=' + Discourse.ShareLink.popupHeight(target)); - return false; + share: function(source) { + var url = source.generateUrl(this.get('link'), this.get('title')); + if (source.shouldOpenInPopup) { + window.open(url, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=600,height=' + (source.popupHeight || 315)); + } else { + window.open(url, '_blank'); + } } }, - shareLinks: function() { - return Discourse.SiteSettings.share_links.split('|').map(function(i) { - if( Discourse.ShareLink.supportedTargets.indexOf(i) >= 0 ) { - return Discourse.ShareLink.create({target: i, link: this.get('link'), topicTitle: this.get('controllers.topic.title')}); - } else { - return null; - } - }, this).compact(); - }.property('link') - + sources: function() { + return Sharing.activeSources(); + }.property() }); diff --git a/app/assets/javascripts/discourse/initializers/sharing-sources.js.es6 b/app/assets/javascripts/discourse/initializers/sharing-sources.js.es6 new file mode 100644 index 00000000000..ccdb15f0f13 --- /dev/null +++ b/app/assets/javascripts/discourse/initializers/sharing-sources.js.es6 @@ -0,0 +1,52 @@ +import Sharing from 'discourse/lib/sharing'; + +export default { + name: 'sharing-sources', + + initialize: function() { + // Backwards compatibility + Discourse.ShareLink = {}; + Discourse.ShareLink.addTarget = function(id, source) { + Ember.warn('Discourse.ShareLink.addTarget is deprecated. Import `Sharing` and call `addSource` instead.'); + source.id = id; + Sharing.addSource(source); + }; + + Sharing.addSource({ + id: 'twitter', + iconClass: 'fa-twitter-square', + generateUrl: function(link, title) { + return "http://twitter.com/intent/tweet?url=" + encodeURIComponent(link) + "&text=" + encodeURIComponent(title); + }, + shouldOpenInPopup: true, + popupHeight: 265 + }); + + Sharing.addSource({ + id: 'facebook', + iconClass: 'fa-facebook-square', + generateUrl: function(link, title) { + return "http://www.facebook.com/sharer.php?u=" + encodeURIComponent(link) + '&t=' + encodeURIComponent(title); + }, + shouldOpenInPopup: true + }); + + Sharing.addSource({ + id: 'google+', + iconClass: 'fa-google-plus-square', + generateUrl: function(link) { + return "https://plus.google.com/share?url=" + encodeURIComponent(link); + }, + shouldOpenInPopup: true, + popupHeight: 600 + }); + + Sharing.addSource({ + id: 'email', + iconClass: 'fa-envelope-square', + generateUrl: function(link, title) { + return "mailto:?to=&subject=" + encodeURIComponent('[' + Discourse.SiteSettings.title + '] ' + title) + "&body=" + encodeURIComponent(link); + } + }); + } +}; diff --git a/app/assets/javascripts/discourse/lib/sharing.js.es6 b/app/assets/javascripts/discourse/lib/sharing.js.es6 new file mode 100644 index 00000000000..6aa23a442f8 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/sharing.js.es6 @@ -0,0 +1,40 @@ +/** + If you want to add a new sharing source to Discourse, you can do so like this: + + ```javascript + import Sharing from 'discourse/lib/sharing'; + + Sharing.addSource({ + + // This id must be present in the `share_links` site setting too + id: 'twitter', + + // The icon that will be displayed + iconClass: 'fa-twitter-square', + + // A callback for generating the remote link from the `link` and `title` + generateUrl: function(link, title) { + return "http://twitter.com/intent/tweet?url=" + encodeURIComponent(link) + "&text=" + encodeURIComponent(title); + }, + + // If true, opens in a popup of `popupHeight` size. If false it's opened in a new tab + shouldOpenInPopup: true, + popupHeight: 265 + }); + ``` +**/ + +var _sources = []; + +export default { + addSource: function (source) { + _sources.push(source); + }, + + activeSources: function() { + var enabled = Discourse.SiteSettings.share_links.split('|'); + return _sources.filter(function(s) { + return enabled.indexOf(s.id) !== -1; + }); + } +}; diff --git a/app/assets/javascripts/discourse/models/share_link.js b/app/assets/javascripts/discourse/models/share_link.js deleted file mode 100644 index ff9ee3dc457..00000000000 --- a/app/assets/javascripts/discourse/models/share_link.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - A data model representing a link to share a post on a 3rd party site, - like Twitter, Facebook, and Google+. - - @class ShareLink - @extends Discourse.Model - @namespace Discourse - @module Discourse -**/ -Discourse.ShareLink = Discourse.Model.extend({ - - href: function() { - return Discourse.ShareLink.urlFor[this.get('target')](this.get('link'), this.get('topicTitle')); - }.property('target', 'link', 'topicTitle'), - - title: Discourse.computed.i18n('target', 'share.%@'), - - iconClass: function() { - return Discourse.ShareLink.iconClasses[this.get('target')]; - }.property('target'), - - openInPopup: function() { - return( Discourse.ShareLink.shouldOpenInPopup[this.get('target')] ); - }.property('target') - -}); - -Discourse.ShareLink.reopenClass({ - supportedTargets: [], - urlFor: {}, - iconClasses: {}, - popupHeights: {}, - shouldOpenInPopup: {}, - - addTarget: function(id, object) { - var self = this; - self.supportedTargets.push(id); - self.urlFor[id] = object.generateUrl; - self.iconClasses[id] = object.iconClass; - self.popupHeights[id] = object.popupHeight || 315; - self.shouldOpenInPopup[id] = object.shouldOpenInPopup; - }, - - popupHeight: function(target) { - return (this.popupHeights[target] || 315); - } -}); - -(function() { - Discourse.ShareLink.addTarget('twitter', { - iconClass: 'fa-twitter-square', - generateUrl: function(link, title) { - return ("http://twitter.com/intent/tweet?url=" + encodeURIComponent(link) + "&text=" + encodeURIComponent(title) ); - }, - shouldOpenInPopup: true, - popupHeight: 265 - }); - - Discourse.ShareLink.addTarget('facebook', { - iconClass: 'fa-facebook-square', - generateUrl: function(link, title) { - return ("http://www.facebook.com/sharer.php?u=" + encodeURIComponent(link) + '&t=' + encodeURIComponent(title)); - }, - shouldOpenInPopup: true, - popupHeight: 315 - }); - - Discourse.ShareLink.addTarget('google+', { - iconClass: 'fa-google-plus-square', - generateUrl: function(link) { - return ("https://plus.google.com/share?url=" + encodeURIComponent(link)); - }, - shouldOpenInPopup: true, - popupHeight: 600 - }); - - Discourse.ShareLink.addTarget('email', { - iconClass: 'fa-envelope-square', - generateUrl: function(link, title) { - return ("mailto:?to=&subject=" + encodeURIComponent('[' + Discourse.SiteSettings.title + '] ' + title) + "&body=" + encodeURIComponent(link)); - }, - shouldOpenInPopup: false - }); -})(); diff --git a/app/assets/javascripts/discourse/templates/components/share-source.hbs b/app/assets/javascripts/discourse/templates/components/share-source.hbs new file mode 100644 index 00000000000..252538793ee --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/share-source.hbs @@ -0,0 +1 @@ + diff --git a/app/assets/javascripts/discourse/templates/share.hbs b/app/assets/javascripts/discourse/templates/share.hbs index 04b70f361fc..0797ac72337 100644 --- a/app/assets/javascripts/discourse/templates/share.hbs +++ b/app/assets/javascripts/discourse/templates/share.hbs @@ -1,17 +1,20 @@ {{#if controller.link}} -

{{view.title}}

+

{{view.title}}

-{{#if date}} - {{displayDate}} -{{/if}} - -
- - -
- -{{each s in shareLinks itemView='share-link'}} - + {{#if date}} + {{displayDate}} + {{/if}} + +
+ + +
+ + {{#each s in sources}} + {{share-source source=s title=title action="share"}} + {{/each}} + + {{/if}} diff --git a/app/assets/javascripts/discourse/templates/share_link.hbs b/app/assets/javascripts/discourse/templates/share_link.hbs deleted file mode 100644 index 44b3c98c8fa..00000000000 --- a/app/assets/javascripts/discourse/templates/share_link.hbs +++ /dev/null @@ -1,5 +0,0 @@ -{{#if s.openInPopup}} - -{{else}} - -{{/if}} diff --git a/app/assets/javascripts/discourse/views/share-link.js.es6 b/app/assets/javascripts/discourse/views/share-link.js.es6 deleted file mode 100644 index bf516ccd8a2..00000000000 --- a/app/assets/javascripts/discourse/views/share-link.js.es6 +++ /dev/null @@ -1,5 +0,0 @@ -export default Ember.View.extend({ - templateName: 'share_link', - tagName: 'div', - classNameBindings: [':social-link'] -}); diff --git a/app/assets/javascripts/discourse/views/share.js.es6 b/app/assets/javascripts/discourse/views/share.js.es6 index 566d5332e8a..0b4b1f75622 100644 --- a/app/assets/javascripts/discourse/views/share.js.es6 +++ b/app/assets/javascripts/discourse/views/share.js.es6 @@ -1,11 +1,3 @@ -/** - This view is used for rendering the "share" interface for a post - - @class ShareView - @extends Discourse.View - @namespace Discourse - @module Discourse -**/ export default Discourse.View.extend({ templateName: 'share', elementId: 'share-link', diff --git a/app/assets/javascripts/main_include.js b/app/assets/javascripts/main_include.js index 63f9997d024..5759d7a9625 100644 --- a/app/assets/javascripts/main_include.js +++ b/app/assets/javascripts/main_include.js @@ -59,6 +59,7 @@ //= require ./discourse/lib/export-result //= require ./discourse/dialects/dialect //= require ./discourse/lib/emoji/emoji +//= require ./discourse/lib/sharing //= require_tree ./discourse/dialects //= require_tree ./discourse/controllers