mirror of
https://github.com/wassname/talk.git
synced 2026-07-13 17:45:56 +08:00
Port to new Slot property passthrough
This commit is contained in:
@@ -63,6 +63,7 @@ export default class Embed extends React.Component {
|
||||
} = this.props;
|
||||
const hasHighlightedComment = !!commentId;
|
||||
const popupUrl = `login?parentUrl=${encodeURIComponent(parentUrl)}`;
|
||||
const slotPassthrough = { data, root };
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -84,7 +85,7 @@ export default class Embed extends React.Component {
|
||||
/>
|
||||
</IfSlotIsNotEmpty>
|
||||
|
||||
<Slot data={data} queryData={{ root }} fill="embed" />
|
||||
<Slot passthrough={slotPassthrough} fill="embed" />
|
||||
|
||||
<ExtendableTabPanel
|
||||
className="talk-embed-stream-tab-bar"
|
||||
@@ -94,8 +95,7 @@ export default class Embed extends React.Component {
|
||||
tabSlot="embedStreamTabs"
|
||||
tabSlotPrepend="embedStreamTabsPrepend"
|
||||
tabPaneSlot="embedStreamTabPanes"
|
||||
slotProps={{ data }}
|
||||
queryData={{ root }}
|
||||
slotPassthrough={slotPassthrough}
|
||||
tabs={this.getTabs()}
|
||||
tabPanes={[
|
||||
<TabPane
|
||||
|
||||
@@ -53,8 +53,7 @@ class ExtendableTabPanelContainer extends React.Component {
|
||||
return plugins.getSlotElements(
|
||||
slot,
|
||||
props.reduxState,
|
||||
props.slotProps,
|
||||
props.queryData
|
||||
props.slotPassthrough
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,8 +131,7 @@ ExtendableTabPanelContainer.propTypes = {
|
||||
tabSlot: PropTypes.string.isRequired,
|
||||
tabSlotPrepend: PropTypes.string.isRequired,
|
||||
tabPaneSlot: PropTypes.string.isRequired,
|
||||
slotProps: PropTypes.object.isRequired,
|
||||
queryData: PropTypes.object,
|
||||
slotPassthrough: PropTypes.object,
|
||||
className: PropTypes.string,
|
||||
sub: PropTypes.bool,
|
||||
loading: PropTypes.bool,
|
||||
|
||||
@@ -25,9 +25,9 @@ class Settings extends React.Component {
|
||||
onQuestionBoxContentChange,
|
||||
canSave,
|
||||
onApply,
|
||||
slotProps,
|
||||
queryData,
|
||||
slotPassthrough,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.container}>
|
||||
@@ -77,7 +77,7 @@ class Settings extends React.Component {
|
||||
</div>
|
||||
)}
|
||||
</Configuration>
|
||||
<Slot fill="streamSettings" queryData={queryData} {...slotProps} />
|
||||
<Slot fill="streamSettings" passthrough={slotPassthrough} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -85,8 +85,7 @@ class Settings extends React.Component {
|
||||
}
|
||||
|
||||
Settings.propTypes = {
|
||||
queryData: PropTypes.object.isRequired,
|
||||
slotProps: PropTypes.object.isRequired,
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
settings: PropTypes.object.isRequired,
|
||||
canSave: PropTypes.bool.isRequired,
|
||||
onToggleModeration: PropTypes.func.isRequired,
|
||||
|
||||
@@ -63,11 +63,20 @@ class SettingsContainer extends React.Component {
|
||||
errors,
|
||||
updatePending,
|
||||
} = this.props;
|
||||
|
||||
const slotPassthrough = {
|
||||
root,
|
||||
asset,
|
||||
settings: mergedSettings,
|
||||
data,
|
||||
updatePending,
|
||||
errors,
|
||||
};
|
||||
|
||||
return (
|
||||
<Settings
|
||||
settings={mergedSettings}
|
||||
queryData={{ root, asset, settings: mergedSettings }}
|
||||
slotProps={{ data, updatePending, errors }}
|
||||
slotPassthrough={slotPassthrough}
|
||||
savePending={this.savePending}
|
||||
onToggleModeration={this.toggleModeration}
|
||||
onTogglePremodLinks={this.togglePremodLinks}
|
||||
|
||||
@@ -24,7 +24,7 @@ class Comment extends React.Component {
|
||||
render() {
|
||||
const { comment, data, root } = this.props;
|
||||
const reactionCount = getTotalReactionsCount(comment.action_summaries);
|
||||
const queryData = { root, comment, asset: comment.asset };
|
||||
const slotPassthrough = { data, root, comment, asset: comment.asset };
|
||||
|
||||
return (
|
||||
<div className={styles.myComment}>
|
||||
@@ -33,8 +33,7 @@ class Comment extends React.Component {
|
||||
fill="commentContent"
|
||||
defaultComponent={CommentContent}
|
||||
className={cn(styles.commentBody, 'my-comment-body')}
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
<div className={cn(styles.commentSummary, 'comment-summary')}>
|
||||
<span
|
||||
@@ -98,9 +97,10 @@ class Comment extends React.Component {
|
||||
fill="historyCommentTimestamp"
|
||||
defaultComponent={CommentTimestamp}
|
||||
className={'talk-history-comment-published-date'}
|
||||
created_at={comment.created_at}
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={{
|
||||
created_at: comment.created_at,
|
||||
...slotPassthrough,
|
||||
}}
|
||||
inline
|
||||
/>
|
||||
</li>
|
||||
|
||||
@@ -14,36 +14,41 @@ const Profile = ({
|
||||
root,
|
||||
activeTab,
|
||||
setActiveTab,
|
||||
}) => (
|
||||
<div className="talk-my-profile talk-profile-container">
|
||||
<div className={styles.userInfo}>
|
||||
<h2 className={styles.username}>{username}</h2>
|
||||
{emailAddress ? <p className={styles.email}>{emailAddress}</p> : null}
|
||||
}) => {
|
||||
const slotPassthrough = {
|
||||
data,
|
||||
root,
|
||||
};
|
||||
return (
|
||||
<div className="talk-my-profile talk-profile-container">
|
||||
<div className={styles.userInfo}>
|
||||
<h2 className={styles.username}>{username}</h2>
|
||||
{emailAddress ? <p className={styles.email}>{emailAddress}</p> : null}
|
||||
</div>
|
||||
<Slot fill="profileSections" passthrough={slotPassthrough} />
|
||||
<ExtendableTabPanel
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
fallbackTab="comments"
|
||||
tabSlot="profileTabs"
|
||||
tabSlotPrepend="profileTabsPrepend"
|
||||
tabPaneSlot="profileTabPanes"
|
||||
slotPassthrough={slotPassthrough}
|
||||
tabs={[
|
||||
<Tab key="comments" tabId="comments">
|
||||
{t('framework.my_comments')}
|
||||
</Tab>,
|
||||
]}
|
||||
tabPanes={[
|
||||
<TabPane key="comments" tabId="comments">
|
||||
<CommentHistory data={data} root={root} />
|
||||
</TabPane>,
|
||||
]}
|
||||
sub
|
||||
/>
|
||||
</div>
|
||||
<Slot fill="profileSections" data={data} queryData={{ root }} />
|
||||
<ExtendableTabPanel
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
fallbackTab="comments"
|
||||
tabSlot="profileTabs"
|
||||
tabSlotPrepend="profileTabsPrepend"
|
||||
tabPaneSlot="profileTabPanes"
|
||||
slotProps={{ data }}
|
||||
queryData={{ root }}
|
||||
tabs={[
|
||||
<Tab key="comments" tabId="comments">
|
||||
{t('framework.my_comments')}
|
||||
</Tab>,
|
||||
]}
|
||||
tabPanes={[
|
||||
<TabPane key="comments" tabId="comments">
|
||||
<CommentHistory data={data} root={root} />
|
||||
</TabPane>,
|
||||
]}
|
||||
sub
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
Profile.propTypes = {
|
||||
username: PropTypes.string,
|
||||
|
||||
@@ -535,12 +535,9 @@ export default class Comment extends React.Component {
|
||||
);
|
||||
|
||||
// props that are passed down the slots.
|
||||
const slotProps = {
|
||||
const slotPassthrough = {
|
||||
data,
|
||||
depth,
|
||||
};
|
||||
|
||||
const queryData = {
|
||||
root,
|
||||
asset,
|
||||
comment,
|
||||
@@ -551,8 +548,7 @@ export default class Comment extends React.Component {
|
||||
<Slot
|
||||
className={cn(styles.commentAvatar, 'talk-stream-comment-avatar')}
|
||||
fill="commentAvatar"
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
|
||||
@@ -573,8 +569,7 @@ export default class Comment extends React.Component {
|
||||
className={cn(styles.username, 'talk-stream-comment-user-name')}
|
||||
fill="commentAuthorName"
|
||||
defaultComponent={CommentAuthorName}
|
||||
queryData={queryData}
|
||||
{...slotProps}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
|
||||
<div
|
||||
@@ -591,8 +586,7 @@ export default class Comment extends React.Component {
|
||||
'talk-stream-comment-author-tags'
|
||||
)}
|
||||
fill="commentAuthorTags"
|
||||
queryData={queryData}
|
||||
{...slotProps}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
@@ -607,9 +601,10 @@ export default class Comment extends React.Component {
|
||||
fill="commentTimestamp"
|
||||
defaultComponent={CommentTimestamp}
|
||||
className={'talk-stream-comment-published-date'}
|
||||
created_at={comment.created_at}
|
||||
queryData={queryData}
|
||||
{...slotProps}
|
||||
passthrough={{
|
||||
created_at: comment.created_at,
|
||||
...slotPassthrough,
|
||||
}}
|
||||
/>
|
||||
{comment.editing && comment.editing.edited ? (
|
||||
<span>
|
||||
@@ -624,8 +619,7 @@ export default class Comment extends React.Component {
|
||||
<Slot
|
||||
className={styles.commentInfoBar}
|
||||
fill="commentInfoBar"
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
|
||||
{isActive &&
|
||||
@@ -665,9 +659,8 @@ export default class Comment extends React.Component {
|
||||
fill="commentContent"
|
||||
className="talk-stream-comment-content"
|
||||
defaultComponent={CommentContent}
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
size={1}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -678,8 +671,7 @@ export default class Comment extends React.Component {
|
||||
<div className="talk-embed-stream-comment-actions-container-left commentActionsLeft comment__action-container">
|
||||
<Slot
|
||||
fill="commentReactions"
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
|
||||
@@ -696,9 +688,7 @@ export default class Comment extends React.Component {
|
||||
<div className="talk-embed-stream-comment-actions-container-right commentActionsRight comment__action-container">
|
||||
<Slot
|
||||
fill="commentActions"
|
||||
wrapperComponent={ActionButton}
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
<ActionButton>
|
||||
|
||||
@@ -43,20 +43,13 @@ export default class DraftArea extends React.Component {
|
||||
charCountEnable,
|
||||
maxCharCount,
|
||||
onChange,
|
||||
queryData,
|
||||
isReply,
|
||||
registerHook,
|
||||
unregisterHook,
|
||||
root,
|
||||
comment,
|
||||
} = this.props;
|
||||
|
||||
const tASettings = {
|
||||
value,
|
||||
placeholder,
|
||||
id,
|
||||
onChange,
|
||||
rows,
|
||||
disabled,
|
||||
isReply,
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
@@ -69,10 +62,19 @@ export default class DraftArea extends React.Component {
|
||||
fill="draftArea"
|
||||
defaultComponent={DraftAreaContent}
|
||||
className={styles.content}
|
||||
queryData={queryData}
|
||||
registerHook={this.props.registerHook}
|
||||
unregisterHook={this.props.unregisterHook}
|
||||
{...tASettings}
|
||||
passthrough={{
|
||||
root,
|
||||
comment,
|
||||
registerHook,
|
||||
unregisterHook,
|
||||
value,
|
||||
placeholder,
|
||||
id,
|
||||
onChange,
|
||||
rows,
|
||||
disabled,
|
||||
isReply,
|
||||
}}
|
||||
/>
|
||||
<Slot fill="commentInputArea" />
|
||||
</div>
|
||||
@@ -96,7 +98,8 @@ DraftArea.propTypes = {
|
||||
onChange: PropTypes.func,
|
||||
disabled: PropTypes.bool,
|
||||
rows: PropTypes.number,
|
||||
queryData: PropTypes.object.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
comment: PropTypes.object,
|
||||
registerHook: PropTypes.func,
|
||||
unregisterHook: PropTypes.func,
|
||||
isReply: PropTypes.bool,
|
||||
|
||||
@@ -147,15 +147,14 @@ class Stream extends React.Component {
|
||||
loading,
|
||||
} = this.props;
|
||||
|
||||
const slotProps = { data };
|
||||
const slotQueryData = { root, asset };
|
||||
const slotPassthrough = { data, root, asset };
|
||||
|
||||
// `key` of `ExtendableTabPanel` depends on sorting so that we always reset
|
||||
// the state when changing sorting.
|
||||
return (
|
||||
<div className={cn('talk-stream-tab-container', styles.tabContainer)}>
|
||||
<div className={cn('talk-stream-filter-wrapper', styles.filterWrapper)}>
|
||||
<Slot fill="streamFilter" queryData={slotQueryData} {...slotProps} />
|
||||
<Slot fill="streamFilter" passthrough={slotPassthrough} />
|
||||
</div>
|
||||
|
||||
<ExtendableTabPanel
|
||||
@@ -166,8 +165,7 @@ class Stream extends React.Component {
|
||||
tabSlot="streamTabs"
|
||||
tabSlotPrepend="streamTabsPrepend"
|
||||
tabPaneSlot="streamTabPanes"
|
||||
slotProps={slotProps}
|
||||
queryData={slotQueryData}
|
||||
slotPassthrough={slotPassthrough}
|
||||
loading={loading}
|
||||
tabs={
|
||||
<Tab tabId={'all'} key="all">
|
||||
@@ -243,13 +241,13 @@ class Stream extends React.Component {
|
||||
!changedUsername &&
|
||||
!highlightedComment) ||
|
||||
keepCommentBox);
|
||||
const slotProps = { data };
|
||||
const slotQueryData = { root, asset };
|
||||
|
||||
if (highlightedComment === null) {
|
||||
return <StreamError>{t('stream.comment_not_found')}</StreamError>;
|
||||
}
|
||||
|
||||
const slotPassthrough = { data, root, asset };
|
||||
|
||||
return (
|
||||
<div id="stream" className={styles.root}>
|
||||
{open ? (
|
||||
@@ -263,11 +261,7 @@ class Stream extends React.Component {
|
||||
content={asset.settings.questionBoxContent}
|
||||
icon={asset.settings.questionBoxIcon}
|
||||
>
|
||||
<Slot
|
||||
fill="streamQuestionArea"
|
||||
queryData={slotQueryData}
|
||||
{...slotProps}
|
||||
/>
|
||||
<Slot fill="streamQuestionArea" passthrough={slotPassthrough} />
|
||||
</QuestionBox>
|
||||
)}
|
||||
{!banned &&
|
||||
@@ -304,7 +298,7 @@ class Stream extends React.Component {
|
||||
<p>{asset.settings.closedMessage}</p>
|
||||
)}
|
||||
|
||||
<Slot fill="stream" queryData={slotQueryData} {...slotProps} />
|
||||
<Slot fill="stream" passthrough={slotPassthrough} />
|
||||
|
||||
{currentUser && (
|
||||
<ModerationLink
|
||||
|
||||
@@ -190,9 +190,11 @@ class CommentBox extends React.Component {
|
||||
buttonContainerStart={
|
||||
<Slot
|
||||
fill="commentInputDetailArea"
|
||||
registerHook={this.registerHook}
|
||||
unregisterHook={this.unregisterHook}
|
||||
isReply={isReply}
|
||||
passthrough={{
|
||||
registerHook: this.registerHook,
|
||||
unregisterHook: this.unregisterHook,
|
||||
isReply,
|
||||
}}
|
||||
inline
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -42,11 +42,10 @@ class DraftAreaContainer extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const queryData = { comment: this.props.comment, root: this.props.root };
|
||||
|
||||
return (
|
||||
<DraftArea
|
||||
queryData={queryData}
|
||||
root={this.props.root}
|
||||
comment={this.props.comment}
|
||||
value={this.props.value}
|
||||
placeholder={this.props.placeholder}
|
||||
id={this.props.id}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Menu from './Menu';
|
||||
import styles from './AuthorName.css';
|
||||
import { ClickOutside } from 'plugin-api/beta/client/components';
|
||||
import cn from 'classnames';
|
||||
|
||||
export default ({
|
||||
data,
|
||||
root,
|
||||
asset,
|
||||
comment,
|
||||
const AuthorName = ({
|
||||
slotPassthrough,
|
||||
username,
|
||||
contentSlot,
|
||||
menuVisible,
|
||||
toggleMenu,
|
||||
@@ -21,18 +20,23 @@ export default ({
|
||||
className={cn(styles.button, 'talk-plugin-author-menu-button')}
|
||||
onClick={toggleMenu}
|
||||
>
|
||||
<span className={styles.name}>{comment.user.username}</span>
|
||||
<span className={styles.name}>{username}</span>
|
||||
</button>
|
||||
{menuVisible && (
|
||||
<Menu
|
||||
data={data}
|
||||
root={root}
|
||||
asset={asset}
|
||||
comment={comment}
|
||||
contentSlot={contentSlot}
|
||||
/>
|
||||
<Menu slotPassthrough={slotPassthrough} contentSlot={contentSlot} />
|
||||
)}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
};
|
||||
|
||||
AuthorName.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
menuVisible: PropTypes.bool.isRequired,
|
||||
toggleMenu: PropTypes.func.isRequired,
|
||||
hideMenu: PropTypes.func.isRequired,
|
||||
contentSlot: PropTypes.string,
|
||||
};
|
||||
|
||||
export default AuthorName;
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Menu.css';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
import cn from 'classnames';
|
||||
|
||||
export default ({ data, root, asset, comment, contentSlot }) => {
|
||||
const Menu = ({ slotPassthrough, contentSlot }) => {
|
||||
if (contentSlot) {
|
||||
return (
|
||||
<div className={cn(styles.menu, 'talk-plugin-author-menu-popup')}>
|
||||
<Slot
|
||||
fill={contentSlot}
|
||||
data={data}
|
||||
queryData={{ asset, root, comment }}
|
||||
/>
|
||||
<Slot fill={contentSlot} passthrough={slotPassthrough} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -21,15 +18,20 @@ export default ({ data, root, asset, comment, contentSlot }) => {
|
||||
<Slot
|
||||
className={cn('talk-plugin-author-menu-infos')}
|
||||
fill={'authorMenuInfos'}
|
||||
data={data}
|
||||
queryData={{ asset, root, comment }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
<Slot
|
||||
className={cn(styles.actions, 'talk-plugin-author-menu-actions')}
|
||||
fill={'authorMenuActions'}
|
||||
data={data}
|
||||
queryData={{ asset, root, comment }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Menu.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
contentSlot: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect, withFragments } from 'plugin-api/beta/client/hocs';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import AuthorName from '../components/AuthorName';
|
||||
@@ -47,21 +48,41 @@ class AuthorNameContainer extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
data,
|
||||
root,
|
||||
asset,
|
||||
comment,
|
||||
contentSlot,
|
||||
showMenuForComment,
|
||||
} = this.props;
|
||||
|
||||
const slotPassthrough = { data, root, asset, comment };
|
||||
|
||||
return (
|
||||
<AuthorName
|
||||
data={this.props.data}
|
||||
root={this.props.root}
|
||||
asset={this.props.asset}
|
||||
comment={this.props.comment}
|
||||
contentSlot={this.props.contentSlot}
|
||||
menuVisible={this.props.showMenuForComment === this.props.comment.id}
|
||||
username={comment.user.username}
|
||||
contentSlot={contentSlot}
|
||||
menuVisible={showMenuForComment === comment.id}
|
||||
toggleMenu={this.toggleMenu}
|
||||
hideMenu={this.hideMenu}
|
||||
slotPassthrough={slotPassthrough}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AuthorNameContainer.propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
asset: PropTypes.object.isRequired,
|
||||
comment: PropTypes.object.isRequired,
|
||||
contentSlot: PropTypes.string,
|
||||
showMenuForComment: PropTypes.string,
|
||||
openMenu: PropTypes.func.isRequired,
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const slots = ['authorMenuInfos', 'authorMenuActions'];
|
||||
|
||||
const mapStateToProps = ({ talkPluginAuthorMenu: state }) => ({
|
||||
|
||||
@@ -19,7 +19,7 @@ class Comment extends React.Component {
|
||||
|
||||
render() {
|
||||
const { comment, asset, root, data } = this.props;
|
||||
const queryData = { comment, asset, root };
|
||||
const slotPassthrough = { data, comment, asset, root };
|
||||
return (
|
||||
<div className={cn(styles.root, `${pluginName}-comment`)}>
|
||||
<Slot
|
||||
@@ -27,8 +27,7 @@ class Comment extends React.Component {
|
||||
className={cn(styles.quote, `${pluginName}-comment-body`)}
|
||||
fill="commentContent"
|
||||
defaultComponent={CommentContent}
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
|
||||
<div className={cn(`${pluginName}-comment-username-box`)}>
|
||||
@@ -36,8 +35,7 @@ class Comment extends React.Component {
|
||||
className={cn(styles.username, `${pluginName}-comment-username`)}
|
||||
fill="commentAuthorName"
|
||||
defaultComponent={CommentAuthorName}
|
||||
queryData={queryData}
|
||||
data={data}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
|
||||
@@ -45,9 +43,7 @@ class Comment extends React.Component {
|
||||
fill="commentTimestamp"
|
||||
defaultComponent={CommentTimestamp}
|
||||
className={cn(styles.timestamp, `${pluginName}-comment-timestamp`)}
|
||||
created_at={comment.created_at}
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={{ created_at: comment.created_at, ...slotPassthrough }}
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
@@ -62,10 +58,7 @@ class Comment extends React.Component {
|
||||
>
|
||||
<Slot
|
||||
fill="commentReactions"
|
||||
root={root}
|
||||
data={data}
|
||||
comment={comment}
|
||||
asset={asset}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ class FlagDetails extends Component {
|
||||
}, {});
|
||||
|
||||
const reasons = Object.keys(summaries);
|
||||
const queryData = {
|
||||
const slotPassthrough = {
|
||||
data,
|
||||
root,
|
||||
comment,
|
||||
};
|
||||
@@ -52,12 +53,11 @@ class FlagDetails extends Component {
|
||||
{more && (
|
||||
<IfSlotIsNotEmpty
|
||||
slot="adminCommentMoreFlagDetails"
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
>
|
||||
<Slot
|
||||
fill="adminCommentMoreFlagDetails"
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</IfSlotIsNotEmpty>
|
||||
)}
|
||||
|
||||
@@ -22,6 +22,12 @@ export default class ModerationActions extends React.Component {
|
||||
hideMenu,
|
||||
} = this.props;
|
||||
|
||||
const slotPassthrough = {
|
||||
comment,
|
||||
asset,
|
||||
data,
|
||||
};
|
||||
|
||||
return (
|
||||
<ClickOutside onClickOutside={hideMenu}>
|
||||
<div
|
||||
@@ -45,8 +51,7 @@ export default class ModerationActions extends React.Component {
|
||||
<Slot
|
||||
className="talk-plugin-modetarion-actions-slot"
|
||||
fill="moderationActions"
|
||||
queryData={{ comment, asset }}
|
||||
data={data}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
<ApproveCommentAction comment={comment} hideMenu={hideMenu} />
|
||||
<RejectCommentAction comment={comment} hideMenu={hideMenu} />
|
||||
|
||||
@@ -29,8 +29,15 @@ class Settings extends React.Component {
|
||||
email,
|
||||
} = this.props;
|
||||
|
||||
const slotPassthrough = {
|
||||
root,
|
||||
setTurnOffInputFragment,
|
||||
updateNotificationSettings,
|
||||
disabled: needEmailVerification,
|
||||
};
|
||||
|
||||
return (
|
||||
<IfSlotIsNotEmpty slot="notificationSettings" queryData={{ root }}>
|
||||
<IfSlotIsNotEmpty slot="notificationSettings" passthrough={slotPassthrough}>
|
||||
<div className={styles.root}>
|
||||
<h3>{t('talk-plugin-notifications.settings_title')}</h3>
|
||||
{needEmailVerification && <EmailVerificationBanner email={email} />}
|
||||
@@ -45,11 +52,8 @@ class Settings extends React.Component {
|
||||
<Slot
|
||||
className={styles.notifcationSettingsSlot}
|
||||
fill="notificationSettings"
|
||||
queryData={{ root }}
|
||||
childFactory={this.childFactory}
|
||||
setTurnOffInputFragment={setTurnOffInputFragment}
|
||||
updateNotificationSettings={updateNotificationSettings}
|
||||
disabled={needEmailVerification}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
<BareButton
|
||||
className={styles.turnOffButton}
|
||||
|
||||
@@ -5,9 +5,10 @@ import { Slot } from 'plugin-api/beta/client/components';
|
||||
class TabPane extends React.Component {
|
||||
render() {
|
||||
const { data, root } = this.props;
|
||||
const slotPassthrough = { data, root };
|
||||
return (
|
||||
<div>
|
||||
<Slot fill="profileSettings" data={data} queryData={{ root }} />
|
||||
<Slot fill="profileSettings" passthrough={slotPassthrough} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Category.css';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
|
||||
@@ -8,7 +9,7 @@ const childFactory = child => (
|
||||
</li>
|
||||
);
|
||||
|
||||
const ViewingOptions = ({ slot, title, data, asset, root }) => {
|
||||
const Category = ({ slot, title, slotPassthrough }) => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.title}>{title}</div>
|
||||
@@ -17,11 +18,16 @@ const ViewingOptions = ({ slot, title, data, asset, root }) => {
|
||||
childFactory={childFactory}
|
||||
className={styles.list}
|
||||
component={'ul'}
|
||||
data={data}
|
||||
queryData={{ asset, root }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewingOptions;
|
||||
Category.propTypes = {
|
||||
slot: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Category;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './Menu.css';
|
||||
import { capitalize } from 'plugin-api/beta/client/utils';
|
||||
@@ -13,16 +14,19 @@ class Menu extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { slotPassthrough } = this.props;
|
||||
return (
|
||||
<div className={cn([styles.menu, 'talk-plugin-viewing-options-menu'])}>
|
||||
{Object.keys(this.categories).map(category => (
|
||||
<IfSlotIsNotEmpty
|
||||
slot={`viewingOptions${capitalize(category)}`}
|
||||
key={category}
|
||||
passthrough={slotPassthrough}
|
||||
>
|
||||
<Category
|
||||
slot={`viewingOptions${capitalize(category)}`}
|
||||
title={this.categories[category]}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</IfSlotIsNotEmpty>
|
||||
))}
|
||||
@@ -31,4 +35,8 @@ class Menu extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
Menu.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './ViewingOptions.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
@@ -24,7 +25,7 @@ class ViewingOptions extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { open, data, root, asset } = this.props;
|
||||
const { open, slotPassthrough } = this.props;
|
||||
return (
|
||||
<ClickOutside onClickOutside={this.handleClickOutside}>
|
||||
<div className={cn([styles.root, 'talk-plugin-viewing-options'])}>
|
||||
@@ -41,11 +42,18 @@ class ViewingOptions extends React.Component {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{open && <Menu data={data} root={root} asset={asset} />}
|
||||
{open && <Menu slotPassthrough={slotPassthrough} />}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ViewingOptions.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
openMenu: PropTypes.func.isRequired,
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ViewingOptions;
|
||||
|
||||
@@ -4,6 +4,7 @@ import ViewingOptions from '../components/ViewingOptions';
|
||||
import { openMenu, closeMenu } from '../actions';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import { getSlotFragmentSpreads } from 'plugin-api/beta/client/utils';
|
||||
import { mapProps } from 'recompose';
|
||||
|
||||
const slots = ['viewingOptionsSort', 'viewingOptionsFilter'];
|
||||
|
||||
@@ -29,7 +30,17 @@ const withViewingOptionsFragments = withFragments({
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
withViewingOptionsFragments
|
||||
withViewingOptionsFragments,
|
||||
mapProps(({ root, asset, data, open, openMenu, closeMenu }) => ({
|
||||
slotPassthrough: {
|
||||
data,
|
||||
root,
|
||||
asset,
|
||||
},
|
||||
open,
|
||||
openMenu,
|
||||
closeMenu,
|
||||
}))
|
||||
);
|
||||
|
||||
export default enhance(ViewingOptions);
|
||||
|
||||
Reference in New Issue
Block a user