From d972da935a80de6ae96edf1f9b537c1287b82ef2 Mon Sep 17 00:00:00 2001
From: Brett Sun
Date: Mon, 9 Nov 2015 17:46:49 +0100
Subject: [PATCH] Add Facebook Share button
---
js/app.js | 1 +
.../ascribe_detail/media_container.js | 3 ++
.../facebook_share_button.js | 52 +++++++++++++++++++
js/constants/application_constants.js | 4 ++
js/third_party/facebook.js | 30 +++++++++++
5 files changed, 90 insertions(+)
create mode 100644 js/components/ascribe_social_share/facebook_share_button.js
create mode 100644 js/third_party/facebook.js
diff --git a/js/app.js b/js/app.js
index c9451e47..520bedbd 100644
--- a/js/app.js
+++ b/js/app.js
@@ -30,6 +30,7 @@ import GoogleAnalyticsHandler from './third_party/ga';
import RavenHandler from './third_party/raven';
import IntercomHandler from './third_party/intercom';
import NotificationsHandler from './third_party/notifications';
+import FacebookHandler from './third_party/facebook';
/* eslint-enable */
initLogging();
diff --git a/js/components/ascribe_detail/media_container.js b/js/components/ascribe_detail/media_container.js
index 6ac2f745..9e5126bf 100644
--- a/js/components/ascribe_detail/media_container.js
+++ b/js/components/ascribe_detail/media_container.js
@@ -7,6 +7,8 @@ import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import MediaPlayer from './../ascribe_media/media_player';
+import FacebookShareButton from '../ascribe_social_share/facebook_share_button';
+
import CollapsibleButton from './../ascribe_collapsible/collapsible_button';
import AclProxy from '../acl_proxy';
@@ -95,6 +97,7 @@ let MediaContainer = React.createClass({
Download
+
{embed}
diff --git a/js/components/ascribe_social_share/facebook_share_button.js b/js/components/ascribe_social_share/facebook_share_button.js
new file mode 100644
index 00000000..98350347
--- /dev/null
+++ b/js/components/ascribe_social_share/facebook_share_button.js
@@ -0,0 +1,52 @@
+'use strict';
+
+import React from 'react';
+
+import AppConstants from '../../constants/application_constants';
+
+import { InjectInHeadUtils } from '../../utils/inject_utils';
+
+let FacebookShareButton = React.createClass({
+ propTypes: {
+ url: React.PropTypes.string,
+ type: React.PropTypes.string
+ },
+
+ getDefaultProps() {
+ return {
+ type: 'button'
+ };
+ },
+
+ componentDidMount() {
+ /**
+ * Ideally we would only use FB.XFBML.parse() on the component that we're
+ * mounting, but doing this when we first load the FB sdk causes unpredictable behaviour.
+ * The button sometimes doesn't get initialized, likely because FB hasn't properly
+ * been initialized yet.
+ *
+ * To circumvent this, we always have the sdk parse the entire DOM on the initial load
+ * (see FacebookHandler) and then use FB.XFBML.parse() on the mounting component later.
+ */
+ if (!InjectInHeadUtils.isPresent('script', AppConstants.facebook.sdkUrl)) {
+ InjectInHeadUtils.inject(AppConstants.facebook.sdkUrl);
+ } else {
+ // Parse() searches the children of the element we give it, not the element itself.
+ FB.XFBML.parse(this.refs.fbShareButton.getDOMNode().parentElement);
+ }
+ },
+
+ render() {
+ return (
+
+
+ );
+ }
+});
+
+export default FacebookShareButton;
diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js
index 0fe5e210..b86bb594 100644
--- a/js/constants/application_constants.js
+++ b/js/constants/application_constants.js
@@ -75,6 +75,10 @@ let constants = {
'raven': {
'url': 'https://0955da3388c64ab29bd32c2a429f9ef4@app.getsentry.com/48351'
},
+ 'facebook': {
+ 'appId': '420813844732240',
+ 'sdkUrl': '//connect.facebook.net/en_US/sdk.js'
+ },
'copyrightAssociations': ['ARS', 'DACS', 'Bildkunst', 'Pictoright', 'SODRAC', 'Copyright Agency/Viscopy', 'SAVA',
'Bildrecht GmbH', 'SABAM', 'AUTVIS', 'CREAIMAGEN', 'SONECA', 'Copydan', 'EAU', 'Kuvasto', 'GCA', 'HUNGART',
'IVARO', 'SIAE', 'JASPAR-SPDA', 'AKKA/LAA', 'LATGA-A', 'SOMAAP', 'ARTEGESTION', 'CARIER', 'BONO', 'APSAV',
diff --git a/js/third_party/facebook.js b/js/third_party/facebook.js
new file mode 100644
index 00000000..eab0b0e0
--- /dev/null
+++ b/js/third_party/facebook.js
@@ -0,0 +1,30 @@
+'use strict';
+
+import { altThirdParty } from '../alt';
+import EventActions from '../actions/event_actions';
+
+import AppConstants from '../constants/application_constants'
+
+class FacebookHandler {
+ constructor() {
+ this.bindActions(EventActions);
+ }
+
+ onApplicationWillBoot(settings) {
+ // Callback function that FB's sdk will call when it's finished loading
+ // See https://developers.facebook.com/docs/javascript/quickstart/v2.5
+ window.fbAsyncInit = () => {
+ FB.init({
+ appId: AppConstants.facebook.appId,
+ // Force FB to parse everything on first load to make sure all the XFBML components are initialized.
+ // If we don't do this, we can run into issues with components on the first load who are not be
+ // initialized.
+ xfbml: true,
+ version: 'v2.5',
+ cookie: false
+ });
+ };
+ }
+}
+
+export default altThirdParty.createStore(FacebookHandler, 'FacebookHandler');