+
{children}
);
@@ -21,7 +23,9 @@ Slot.propTypes = {
fill: React.PropTypes.string
};
-const mapStateToProps = ({config: {plugin_config = {}}}) => ({plugin_config});
+const mapStateToProps = (state) => ({
+ reduxState: omit(state, 'apollo'),
+});
export default connect(mapStateToProps, null)(Slot);
diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js
index 57bde6f3f..324f75f44 100644
--- a/client/coral-framework/constants/auth.js
+++ b/client/coral-framework/constants/auth.js
@@ -3,6 +3,8 @@ export const CLEAN_STATE = 'CLEAN_STATE';
export const SHOW_SIGNIN_DIALOG = 'SHOW_SIGNIN_DIALOG';
export const HIDE_SIGNIN_DIALOG = 'HIDE_SIGNIN_DIALOG';
+export const FOCUS_SIGNIN_DIALOG = 'FOCUS_SIGNIN_DIALOG';
+export const BLUR_SIGNIN_DIALOG = 'BLUR_SIGNIN_DIALOG';
export const CREATE_USERNAME_REQUEST = 'CREATE_USERNAME_REQUEST';
export const CREATE_USERNAME_SUCCESS = 'CREATE_USERNAME_SUCCESS';
diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js
index d60329baa..cc8147c19 100644
--- a/client/coral-framework/helpers/plugins.js
+++ b/client/coral-framework/helpers/plugins.js
@@ -6,32 +6,42 @@ import plugins from 'pluginsConfig';
import flatten from 'lodash/flatten';
import flattenDeep from 'lodash/flattenDeep';
import {loadTranslations} from 'coral-framework/services/i18n';
-import {injectReducers, getStore} from 'coral-framework/services/store';
+import {injectReducers} from 'coral-framework/services/store';
import camelize from './camelize';
-export function getSlotComponents(slot) {
- const pluginConfig = getStore().getState().config.plugin_config;
-
+export function getSlotComponents(slot, reduxState, props = {}) {
+ const pluginConfig = reduxState.config.pluginConfig || {};
return flatten(plugins
- // Filter out components that have slots and have been disabled in `plugin_config`
+ // Filter out components that have slots and have been disabled in `plugin_config`
.filter((o) => o.module.slots && (!pluginConfig || !pluginConfig[o.name] || !pluginConfig[o.name].disable_components))
.filter((o) => o.module.slots[slot])
.map((o) => o.module.slots[slot])
- );
+ )
+ .filter((component) => {
+ if(!component.isExcluded) {
+ return true;
+ }
+ let resolvedProps = {...props, config: pluginConfig};
+ if (component.mapStateToProps) {
+ resolvedProps = {...resolvedProps, ...component.mapStateToProps(reduxState)};
+ }
+ return !component.isExcluded(resolvedProps);
+ });
}
-export function isSlotEmpty(slot) {
- return getSlotComponents(slot).length === 0;
+export function isSlotEmpty(slot, reduxState, props) {
+ return getSlotComponents(slot, reduxState, props).length === 0;
}
/**
* Returns React Elements for given slot.
*/
-export function getSlotElements(slot, props = {}) {
- return getSlotComponents(slot)
- .map((component, i) => React.createElement(component, {key: i, ...props}));
+export function getSlotElements(slot, reduxState, props = {}) {
+ const pluginConfig = reduxState.config.pluginConfig || {};
+ return getSlotComponents(slot, reduxState, props)
+ .map((component, i) => React.createElement(component, {key: i, ...props, config: pluginConfig}));
}
export function getSlotFragments(slot, part) {
diff --git a/client/coral-framework/hocs/connect.js b/client/coral-framework/hocs/connect.js
new file mode 100644
index 000000000..c49fe8380
--- /dev/null
+++ b/client/coral-framework/hocs/connect.js
@@ -0,0 +1,6 @@
+import {connect} from 'react-redux';
+
+export default (mapStateToProps, ...rest) => (BaseComponent) => {
+ BaseComponent.mapStateToProps = mapStateToProps;
+ return connect(mapStateToProps, ...rest)(BaseComponent);
+};
diff --git a/client/coral-framework/hocs/excludeIf.js b/client/coral-framework/hocs/excludeIf.js
new file mode 100644
index 000000000..ec2f0f27a
--- /dev/null
+++ b/client/coral-framework/hocs/excludeIf.js
@@ -0,0 +1,4 @@
+export default (condition) => (BaseComponent) => {
+ BaseComponent.isExcluded = condition;
+ return BaseComponent;
+};
diff --git a/client/coral-framework/hocs/withFragments.js b/client/coral-framework/hocs/withFragments.js
index d62d62ae3..62e96444c 100644
--- a/client/coral-framework/hocs/withFragments.js
+++ b/client/coral-framework/hocs/withFragments.js
@@ -1,14 +1,5 @@
-import React from 'react';
-import {getDisplayName} from '../helpers/hoc';
-
// TODO: revisit `filtering` after https://github.com/apollographql/graphql-anywhere/issues/38.
-export default (fragments) => (WrappedComponent) => {
- class WithFragments extends React.Component {
- render() {
- return
;
- }
- }
- WithFragments.fragments = fragments;
- WithFragments.displayName = `WithFragments(${getDisplayName(WrappedComponent)})`;
- return WithFragments;
+export default (fragments) => (BaseComponent) => {
+ BaseComponent.fragments = fragments;
+ return BaseComponent;
};
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index 92d676abe..5481b7a5e 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -7,6 +7,7 @@ const initialState = Map({
loggedIn: false,
user: null,
showSignInDialog: false,
+ signInDialogFocus: false,
showCreateUsernameDialog: false,
checkedInitialLogin: false,
view: 'SIGNIN',
@@ -29,13 +30,21 @@ const purge = (user) => {
export default function auth (state = initialState, action) {
switch (action.type) {
+ case actions.FOCUS_SIGNIN_DIALOG:
+ return state
+ .set('signInDialogFocus', true);
+ case actions.BLUR_SIGNIN_DIALOG:
+ return state
+ .set('signInDialogFocus', false);
case actions.SHOW_SIGNIN_DIALOG :
return state
- .set('showSignInDialog', true);
+ .set('showSignInDialog', true)
+ .set('signInDialogFocus', true);
case actions.HIDE_SIGNIN_DIALOG :
return state.merge(Map({
isLoading: false,
showSignInDialog: false,
+ signInDialogFocus: false,
view: 'SIGNIN',
error: '',
passwordRequestFailure: null,
diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js
index 7f3476cfd..78408f6c2 100644
--- a/plugin-api/beta/client/hocs/index.js
+++ b/plugin-api/beta/client/hocs/index.js
@@ -1,2 +1,4 @@
export {default as withReaction} from './withReaction';
export {default as withFragments} from 'coral-framework/hocs/withFragments';
+export {default as excludeIf} from 'coral-framework/hocs/excludeIf';
+export {default as connect} from 'coral-framework/hocs/connect';
diff --git a/plugin-api/beta/client/hocs/withReaction.js b/plugin-api/beta/client/hocs/withReaction.js
index 72de7f5c4..f7be6e701 100644
--- a/plugin-api/beta/client/hocs/withReaction.js
+++ b/plugin-api/beta/client/hocs/withReaction.js
@@ -1,7 +1,7 @@
import React from 'react';
import get from 'lodash/get';
import uuid from 'uuid/v4';
-import {connect} from 'react-redux';
+import {connect} from 'plugin-api/beta/client/hocs';
import {bindActionCreators} from 'redux';
import {getDisplayName} from 'coral-framework/helpers/hoc';
import {compose, gql} from 'react-apollo';
diff --git a/plugin-api/beta/client/selectors/index.js b/plugin-api/beta/client/selectors/index.js
new file mode 100644
index 000000000..09e25d453
--- /dev/null
+++ b/plugin-api/beta/client/selectors/index.js
@@ -0,0 +1 @@
+export const pluginConfigSelector = (state) => state.config.pluginConfig;
diff --git a/plugin-api/beta/client/services/index.js b/plugin-api/beta/client/services/index.js
index ddaa346ab..4e94a782a 100644
--- a/plugin-api/beta/client/services/index.js
+++ b/plugin-api/beta/client/services/index.js
@@ -1,3 +1,9 @@
export {t} from 'coral-framework/services/i18n';
export {can} from 'coral-framework/services/perms';
-export {isSlotEmpty} from 'coral-framework/helpers/plugins';
+import {isSlotEmpty as ise} from 'coral-framework/helpers/plugins';
+
+// @TODO: Deprecated.
+export function isSlotEmpty(...args) {
+ console.warn('A plugin is using `isSlotEmpty` which has been deprecated, please port to the new API using the `IfSlotIsEmpty` and `IfSlotIsNotEmpty` components.');
+ return ise(...args);
+}
diff --git a/plugins/coral-plugin-offtopic/client/containers/OffTopicCheckbox.js b/plugins/coral-plugin-offtopic/client/containers/OffTopicCheckbox.js
index 286fa8d9d..f8471344b 100644
--- a/plugins/coral-plugin-offtopic/client/containers/OffTopicCheckbox.js
+++ b/plugins/coral-plugin-offtopic/client/containers/OffTopicCheckbox.js
@@ -1,7 +1,7 @@
-import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {addTag, removeTag} from 'plugin-api/alpha/client/actions';
import {commentBoxTagsSelector} from 'plugin-api/alpha/client/selectors';
+import {connect} from 'plugin-api/beta/client/hocs';
import OffTopicCheckbox from '../components/OffTopicCheckbox';
const mapStateToProps = (state) => ({
diff --git a/plugins/coral-plugin-offtopic/client/containers/OffTopicFilter.js b/plugins/coral-plugin-offtopic/client/containers/OffTopicFilter.js
index 98f5f7aea..6bca55638 100644
--- a/plugins/coral-plugin-offtopic/client/containers/OffTopicFilter.js
+++ b/plugins/coral-plugin-offtopic/client/containers/OffTopicFilter.js
@@ -1,4 +1,4 @@
-import {connect} from 'react-redux';
+import {connect} from 'plugin-api/beta/client/hocs';
import {bindActionCreators} from 'redux';
import {toggleCheckbox} from '../actions';
import {commentClassNamesSelector} from 'plugin-api/alpha/client/selectors';
diff --git a/plugins/coral-plugin-viewing-options/client/containers/ViewingOptions.js b/plugins/coral-plugin-viewing-options/client/containers/ViewingOptions.js
index 767a9197d..cbe1e7fa3 100644
--- a/plugins/coral-plugin-viewing-options/client/containers/ViewingOptions.js
+++ b/plugins/coral-plugin-viewing-options/client/containers/ViewingOptions.js
@@ -1,4 +1,4 @@
-import {connect} from 'react-redux';
+import {connect} from 'plugin-api/beta/client/hocs';
import {bindActionCreators} from 'redux';
import ViewingOptions from '../components/ViewingOptions';
import {openViewingOptions, closeViewingOptions} from '../actions';