diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js index 5ce7021fb..132b3be7f 100644 --- a/client/coral-embed-stream/src/components/Embed.js +++ b/client/coral-embed-stream/src/components/Embed.js @@ -5,7 +5,8 @@ import Slot from 'coral-framework/components/Slot'; import {can} from 'coral-framework/services/perms'; import t from 'coral-framework/services/i18n'; -import {TabBar, Tab, TabContent, TabPane} from 'coral-ui'; +import ExtendableTabPanel from '../containers/ExtendableTabPanel'; +import {Tab, TabPane} from 'coral-ui'; import ProfileContainer from 'coral-settings/containers/ProfileContainer'; import Popup from 'coral-framework/components/Popup'; import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty'; @@ -28,9 +29,28 @@ export default class Embed extends React.Component { this.props.setActiveTab(tab); }; + getTabs() { + const {user} = this.props.auth; + const tabs = [ + + {t('embed_comments_tab')} + , + + {t('framework.my_profile')} + , + ]; + if (can(user, 'UPDATE_CONFIG')) { + tabs.push( + + {t('framework.configure_stream')} + + ); + } + return tabs; + } + render() { const {activeTab, commentId, root, data, auth: {showSignInDialog, signInDialogFocus}, blurSignInDialog, focusSignInDialog, hideSignInDialog, router: {location: {query: {parentUrl}}}} = this.props; - const {user} = this.props.auth; const hasHighlightedComment = !!commentId; return ( @@ -47,44 +67,36 @@ export default class Embed extends React.Component { onClose={hideSignInDialog} /> - - - {t('embed_comments_tab')} - - - {t('framework.my_profile')} - - {can(user, 'UPDATE_CONFIG') && - - {t('framework.configure_stream')} - - } - + - - - - - - - - - - - + setActiveTab={this.changeTab} + fallbackTab='stream' + tabSlot='embedStreamTabs' + tabSlotPrepend='embedStreamTabsPrepend' + tabPaneSlot='embedStreamTabPanes' + slotProps={{data}} + queryData={{root}} + tabs={this.getTabs()} + tabPanes={[ + + + , + + + , + + + , + ]} + /> ); } diff --git a/client/coral-embed-stream/src/components/StreamTabPanel.css b/client/coral-embed-stream/src/components/ExtendableTabPanel.css similarity index 100% rename from client/coral-embed-stream/src/components/StreamTabPanel.css rename to client/coral-embed-stream/src/components/ExtendableTabPanel.css diff --git a/client/coral-embed-stream/src/components/StreamTabPanel.js b/client/coral-embed-stream/src/components/ExtendableTabPanel.js similarity index 85% rename from client/coral-embed-stream/src/components/StreamTabPanel.js rename to client/coral-embed-stream/src/components/ExtendableTabPanel.js index 35c10d5d9..ec582eb84 100644 --- a/client/coral-embed-stream/src/components/StreamTabPanel.js +++ b/client/coral-embed-stream/src/components/ExtendableTabPanel.js @@ -1,9 +1,9 @@ import React from 'react'; import {Spinner, TabBar, TabContent} from 'coral-ui'; import PropTypes from 'prop-types'; -import styles from './StreamTabPanel.css'; +import styles from './ExtendableTabPanel.css'; -class StreamTabPanel extends React.Component { +class ExtendableTabPanel extends React.Component { render() { const {activeTab, setActiveTab, tabs, tabPanes, sub, loading, ...rest} = this.props; @@ -23,7 +23,7 @@ class StreamTabPanel extends React.Component { } } -StreamTabPanel.propTypes = { +ExtendableTabPanel.propTypes = { activeTab: PropTypes.string.isRequired, setActiveTab: PropTypes.func.isRequired, loading: PropTypes.bool, @@ -39,4 +39,4 @@ StreamTabPanel.propTypes = { sub: PropTypes.bool, }; -export default StreamTabPanel; +export default ExtendableTabPanel; diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index 7ff48106b..084586eeb 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -19,7 +19,7 @@ import cn from 'classnames'; import {getTopLevelParent, attachCommentToParent} from '../graphql/utils'; import AllCommentsPane from './AllCommentsPane'; import AutomaticAssetClosure from '../containers/AutomaticAssetClosure'; -import StreamTabPanel from '../containers/StreamTabPanel'; +import ExtendableTabPanel from '../containers/ExtendableTabPanel'; import styles from './Stream.css'; @@ -106,7 +106,7 @@ class Stream extends React.Component { ); } - renderTabPanel() { + renderExtendableTabPanel() { const { data, root, @@ -135,7 +135,7 @@ class Stream extends React.Component { const slotProps = {data}; const slotQueryData = {root, asset}; - // `key` of `StreamTabPanel` depends on sorting so that we always reset + // `key` of `ExtendableTabPanel` depends on sorting so that we always reset // the state when changing sorting. return (
@@ -148,23 +148,24 @@ class Stream extends React.Component { {...slotProps} />
- {t('stream.all_comments')} {totalCommentCount} } - appendTabPanes={ - + tabPanes={ + ); @@ -325,7 +326,7 @@ Stream.propTypes = { loading: PropTypes.bool, editName: PropTypes.func, appendItemArray: PropTypes.func, - updateItem: PropTypes.func, + updateItem: PropTypes.func, viewAllComments: PropTypes.func, notify: PropTypes.func.isRequired, postComment: PropTypes.func.isRequired, diff --git a/client/coral-embed-stream/src/containers/Embed.js b/client/coral-embed-stream/src/containers/Embed.js index 132e7f5e7..3fef8872d 100644 --- a/client/coral-embed-stream/src/containers/Embed.js +++ b/client/coral-embed-stream/src/containers/Embed.js @@ -151,6 +151,9 @@ const USERNAME_REJECTED_SUBSCRIPTION = gql` const slots = [ 'embed', + 'embedStreamTabs', + 'embedStreamTabsPrepend', + 'embedStreamTabPanes', ]; const EMBED_QUERY = gql` diff --git a/client/coral-embed-stream/src/containers/StreamTabPanel.js b/client/coral-embed-stream/src/containers/ExtendableTabPanel.js similarity index 66% rename from client/coral-embed-stream/src/containers/StreamTabPanel.js rename to client/coral-embed-stream/src/containers/ExtendableTabPanel.js index 9a154512d..b582f7b66 100644 --- a/client/coral-embed-stream/src/containers/StreamTabPanel.js +++ b/client/coral-embed-stream/src/containers/ExtendableTabPanel.js @@ -1,5 +1,5 @@ import React from 'react'; -import StreamTabPanel from '../components/StreamTabPanel'; +import ExtendableTabPanel from '../components/ExtendableTabPanel'; import {connect} from 'react-redux'; import omit from 'lodash/omit'; import {Tab, TabPane} from 'coral-ui'; @@ -7,17 +7,17 @@ import {getShallowChanges} from 'coral-framework/utils'; import isEqual from 'lodash/isEqual'; import PropTypes from 'prop-types'; -class StreamTabPanelContainer extends React.Component { +class ExtendableTabPanelContainer extends React.Component { static contextTypes = { plugins: PropTypes.object, }; componentDidMount() { - this.fallbackAllTab(); + this.handleFallback(); } componentWillReceiveProps(next) { - this.fallbackAllTab(next); + this.handleFallback(next); } shouldComponentUpdate(next) { @@ -35,22 +35,31 @@ class StreamTabPanelContainer extends React.Component { return changes.length !== 0; } - fallbackAllTab(props = this.props) { - if (props.activeTab !== props.fallbackTab) { - const slotPlugins = this.getSlotElements(props.tabSlot, props).map((el) => el.type.talkPluginName); - if (slotPlugins.indexOf(props.activeTab) === -1) { - props.setActiveTab(props.fallbackTab); - } + handleFallback(props = this.props) { + if (this.getTabNames(props).indexOf(props.activeTab) === -1) { + props.setActiveTab(props.fallbackTab); } } + getTabNames(props = this.props) { + return this.getTabElements(props).map((el) => el.props.tabId); + } + getSlotElements(slot, props = this.props) { const {plugins} = this.context; return plugins.getSlotElements(slot, props.reduxState, props.slotProps, props.queryData); } getPluginTabElements(props = this.props) { - return this.getSlotElements(props.tabSlot).map((el) => { + return this.getSlotTabElements(props.tabSlot); + } + + getPluginTabElementsPrepend(props = this.props) { + return this.getSlotTabElements(props.tabSlotPrepend); + } + + getSlotTabElements(slot) { + return this.getSlotElements(slot).map((el) => { return ( {React.cloneElement(el, {active: this.props.activeTab === el.type.talkPluginName})} @@ -59,6 +68,17 @@ class StreamTabPanelContainer extends React.Component { }); } + getTabElements(props = this.props) { + const elements = [...this.getPluginTabElementsPrepend(props)]; + if (Array.isArray(props.tabs)) { + elements.push(...props.tabs); + } else { + elements.push(props.tabs); + } + elements.push(...this.getPluginTabElements(props)); + return elements; + } + getPluginTabPaneElements(props = this.props) { return this.getSlotElements(props.tabPaneSlot).map((el) => { return ( @@ -71,12 +91,12 @@ class StreamTabPanelContainer extends React.Component { render() { return ( - @@ -84,19 +104,20 @@ class StreamTabPanelContainer extends React.Component { } } -StreamTabPanelContainer.propTypes = { +ExtendableTabPanelContainer.propTypes = { activeTab: PropTypes.string.isRequired, setActiveTab: PropTypes.func.isRequired, - appendTabs: PropTypes.oneOfType([ + tabs: PropTypes.oneOfType([ PropTypes.element, PropTypes.arrayOf(PropTypes.element) ]), - appendTabPanes: PropTypes.oneOfType([ + tabPanes: PropTypes.oneOfType([ PropTypes.element, PropTypes.arrayOf(PropTypes.element) ]), fallbackTab: PropTypes.string.isRequired, tabSlot: PropTypes.string.isRequired, + tabSlotPrepend: PropTypes.string.isRequired, tabPaneSlot: PropTypes.string.isRequired, slotProps: PropTypes.object.isRequired, queryData: PropTypes.object, @@ -109,4 +130,4 @@ const mapStateToProps = (state) => ({ reduxState: omit(state, 'apollo'), }); -export default connect(mapStateToProps, null)(StreamTabPanelContainer); +export default connect(mapStateToProps, null)(ExtendableTabPanelContainer); diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index 6c3d7b02c..464ce31fc 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -271,6 +271,7 @@ const LOAD_MORE_QUERY = gql` const slots = [ 'streamTabs', + 'streamTabsPrepend', 'streamTabPanes', 'streamFilter', ]; diff --git a/plugins/talk-plugin-featured-comments/client/index.js b/plugins/talk-plugin-featured-comments/client/index.js index 7b419c545..bdcb2f470 100644 --- a/plugins/talk-plugin-featured-comments/client/index.js +++ b/plugins/talk-plugin-featured-comments/client/index.js @@ -16,7 +16,7 @@ export default { reducer, translations, slots: { - streamTabs: [Tab], + streamTabsPrepend: [Tab], streamTabPanes: [TabPane], commentInfoBar: [Tag], moderationActions: [ModActionButton], @@ -57,7 +57,7 @@ export default { } const comment = findCommentInEmbedQuery(previous, variables.id); - + if (previous.asset.comments) { updated = update(previous, { asset: { @@ -101,7 +101,7 @@ export default { updateQueries: { CoralEmbedStream_Embed: (previous) => { let updated = previous; - + if (variables.name !== 'FEATURED') { return; }