From 8c2070e345265a14bd39aa6be98678b5622a811c Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 19 Feb 2018 16:04:43 +0100 Subject: [PATCH 1/4] Refactor Profile --- .../src/components/Embed.js | 4 +- .../src/tabs/profile/components/Comment.js | 27 ++- .../tabs/profile/components/CommentHistory.js | 8 +- .../src/tabs/profile/components/Profile.js | 26 +++ .../src/tabs/profile/containers/Comment.js | 32 ++++ .../tabs/profile/containers/CommentHistory.js | 103 ++++++++++ .../src/tabs/profile/containers/Profile.js | 93 +++++++++ .../profile/containers/ProfileContainer.js | 178 ------------------ client/coral-framework/services/pym.js | 6 +- 9 files changed, 278 insertions(+), 199 deletions(-) create mode 100644 client/coral-embed-stream/src/tabs/profile/components/Profile.js create mode 100644 client/coral-embed-stream/src/tabs/profile/containers/Comment.js create mode 100644 client/coral-embed-stream/src/tabs/profile/containers/CommentHistory.js create mode 100644 client/coral-embed-stream/src/tabs/profile/containers/Profile.js delete mode 100644 client/coral-embed-stream/src/tabs/profile/containers/ProfileContainer.js diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js index b7eb6d580..71ff39240 100644 --- a/client/coral-embed-stream/src/components/Embed.js +++ b/client/coral-embed-stream/src/components/Embed.js @@ -9,7 +9,7 @@ import AutomaticAssetClosure from '../containers/AutomaticAssetClosure'; import ExtendableTabPanel from '../containers/ExtendableTabPanel'; import { Tab, TabPane } from 'coral-ui'; -import ProfileContainer from '../tabs/profile/containers/ProfileContainer'; +import Profile from '../tabs/profile/containers/Profile'; import Popup from 'coral-framework/components/Popup'; import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty'; import cn from 'classnames'; @@ -112,7 +112,7 @@ export default class Embed extends React.Component { tabId="profile" className="talk-embed-stream-profile-tab-pane" > - + , { + this.props.navigate(this.props.comment.asset.url); + }; + + goToConversation = () => { + this.props.navigate( + `${this.props.comment.asset.url}?commentId=${this.props.comment.id}` + ); + }; + render() { - const { comment, link, data, root } = this.props; + const { comment, data, root } = this.props; const reactionCount = getTotalReactionsCount(comment.action_summaries); const queryData = { root, comment, asset: comment.asset }; @@ -67,7 +77,7 @@ class Comment extends React.Component { {t('common.story')}:{' '} {comment.asset.title ? comment.asset.title : comment.asset.url} @@ -77,10 +87,7 @@ class Comment extends React.Component {
  • - + {t('view_conversation')} @@ -105,10 +112,10 @@ class Comment extends React.Component { } Comment.propTypes = { - comment: PropTypes.shape({ - id: PropTypes.string, - body: PropTypes.string, - }).isRequired, + comment: PropTypes.object.isRequired, + navigate: PropTypes.func.isRequired, + data: PropTypes.object.isRequired, + root: PropTypes.object.isRequired, }; export default Comment; diff --git a/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js b/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js index a17a347c5..f16e8a119 100644 --- a/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js +++ b/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import Comment from './Comment'; +import Comment from '../containers/Comment'; import LoadMore from './LoadMore'; class CommentHistory extends React.Component { @@ -21,7 +21,7 @@ class CommentHistory extends React.Component { }; render() { - const { link, comments, data, root } = this.props; + const { navigate, comments, data, root } = this.props; return (
    @@ -32,7 +32,7 @@ class CommentHistory extends React.Component { data={data} root={root} comment={comment} - link={link} + navigate={navigate} /> ); })} @@ -51,7 +51,7 @@ class CommentHistory extends React.Component { CommentHistory.propTypes = { comments: PropTypes.object.isRequired, loadMore: PropTypes.func, - link: PropTypes.func, + navigate: PropTypes.func, data: PropTypes.object, root: PropTypes.object, }; diff --git a/client/coral-embed-stream/src/tabs/profile/components/Profile.js b/client/coral-embed-stream/src/tabs/profile/components/Profile.js new file mode 100644 index 000000000..b457e7a1d --- /dev/null +++ b/client/coral-embed-stream/src/tabs/profile/components/Profile.js @@ -0,0 +1,26 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Slot from 'coral-framework/components/Slot'; +import CommentHistory from '../containers/CommentHistory'; + +import t from 'coral-framework/services/i18n'; + +const Profile = ({ username, emailAddress, data, root }) => ( +
    +

    {username}

    + {emailAddress ?

    {emailAddress}

    : null} + +
    +

    {t('framework.my_comments')}

    + +
    +); + +Profile.propTypes = { + username: PropTypes.string, + emailAddress: PropTypes.string, + data: PropTypes.object, + root: PropTypes.object, +}; + +export default Profile; diff --git a/client/coral-embed-stream/src/tabs/profile/containers/Comment.js b/client/coral-embed-stream/src/tabs/profile/containers/Comment.js new file mode 100644 index 000000000..7406d4c5e --- /dev/null +++ b/client/coral-embed-stream/src/tabs/profile/containers/Comment.js @@ -0,0 +1,32 @@ +import { gql, compose } from 'react-apollo'; +import Comment from '../components/Comment'; +import { withFragments } from 'coral-framework/hocs'; +import { getSlotFragmentSpreads } from 'coral-framework/utils'; + +const slots = ['commentContent', 'historyCommentTimestamp']; + +const withCommentFragments = withFragments({ + comment: gql` + fragment TalkEmbedStream_Comment_Fragment on Comment { + id + body + replyCount + action_summaries { + count + __typename + } + asset { + id + title + url + ${getSlotFragmentSpreads(slots, 'asset')} + } + created_at + ${getSlotFragmentSpreads(slots, 'comment')} + } + `, +}); + +const enhance = compose(withCommentFragments); + +export default enhance(Comment); diff --git a/client/coral-embed-stream/src/tabs/profile/containers/CommentHistory.js b/client/coral-embed-stream/src/tabs/profile/containers/CommentHistory.js new file mode 100644 index 000000000..a02225939 --- /dev/null +++ b/client/coral-embed-stream/src/tabs/profile/containers/CommentHistory.js @@ -0,0 +1,103 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { compose, gql } from 'react-apollo'; +import CommentHistory from '../components/CommentHistory'; +import Comment from './Comment'; +import { withFragments } from 'coral-framework/hocs'; + +import { appendNewNodes } from 'plugin-api/beta/client/utils'; +import update from 'immutability-helper'; +import { getDefinitionName } from 'coral-framework/utils'; + +class CommentHistoryContainer extends Component { + navigate = url => { + this.context.pym.sendMessage('navigate', url); + }; + + loadMore = () => { + return this.props.data.fetchMore({ + query: LOAD_MORE_QUERY, + variables: { + limit: 5, + cursor: this.props.root.me.comments.endCursor, + }, + updateQuery: (previous, { fetchMoreResult: { me: { comments } } }) => { + const updated = update(previous, { + me: { + comments: { + nodes: { + $apply: nodes => appendNewNodes(nodes, comments.nodes), + }, + hasNextPage: { $set: comments.hasNextPage }, + endCursor: { $set: comments.endCursor }, + }, + }, + }); + return updated; + }, + }); + }; + + render() { + return ( + + ); + } +} + +CommentHistoryContainer.contextTypes = { + pym: PropTypes.object, +}; + +CommentHistoryContainer.propTypes = { + data: PropTypes.object, + root: PropTypes.object, +}; + +const LOAD_MORE_QUERY = gql` + query TalkEmbedStream_CommentHistory_LoadMoreComments($limit: Int, $cursor: Cursor) { + me { + comments(query: { limit: $limit, cursor: $cursor }) { + nodes { + ...${getDefinitionName(Comment.fragments.comment)} + } + endCursor + hasNextPage + } + } + } + ${Comment.fragments.comment} +`; + +const withCommentHistoryFragments = withFragments({ + root: gql` + fragment TalkEmbedStream_CommentHistory on RootQuery { + me { + comments(query: {limit: 10}) { + nodes { + ...${getDefinitionName(Comment.fragments.comment)} + } + endCursor + hasNextPage + } + } + } + ${Comment.fragments.comment} + `, +}); + +const mapStateToProps = state => ({ + currentUser: state.auth.user, +}); + +export default compose( + connect(mapStateToProps, null), + withCommentHistoryFragments +)(CommentHistoryContainer); diff --git a/client/coral-embed-stream/src/tabs/profile/containers/Profile.js b/client/coral-embed-stream/src/tabs/profile/containers/Profile.js new file mode 100644 index 000000000..2fc768535 --- /dev/null +++ b/client/coral-embed-stream/src/tabs/profile/containers/Profile.js @@ -0,0 +1,93 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { connect } from 'react-redux'; +import { compose, gql } from 'react-apollo'; +import { bindActionCreators } from 'redux'; +import { withQuery } from 'coral-framework/hocs'; +import NotLoggedIn from '../components/NotLoggedIn'; +import { Spinner } from 'coral-ui'; +import Profile from '../components/Profile'; +import CommentHistory from './CommentHistory'; +import { getDefinitionName } from 'coral-framework/utils'; + +import { showSignInDialog } from 'coral-embed-stream/src/actions/login'; +import { getSlotFragmentSpreads } from 'coral-framework/utils'; + +class ProfileContainer extends Component { + componentWillReceiveProps(nextProps) { + if (!this.props.currentUser && nextProps.currentUser) { + // Refetch after login. + this.props.data.refetch(); + } + } + + render() { + const { currentUser, showSignInDialog, root, data } = this.props; + const { me } = this.props.root; + const loading = this.props.data.loading; + + if (this.props.data.error) { + return
    {this.props.data.error.message}
    ; + } + + if (!currentUser) { + return ; + } + + if (loading || !me) { + return ; + } + + const localProfile = currentUser.profiles.find(p => p.provider === 'local'); + const emailAddress = localProfile && localProfile.id; + + return ( + + ); + } +} + +ProfileContainer.propTypes = { + data: PropTypes.object, + root: PropTypes.object, + currentUser: PropTypes.object, + showSignInDialog: PropTypes.func, +}; + +const slots = ['profileSections']; + +const withProfileQuery = withQuery( + gql` + query CoralEmbedStream_Profile { + me { + id + username + } + ...${getDefinitionName(CommentHistory.fragments.root)} + ${getSlotFragmentSpreads(slots, 'root')} + } + ${CommentHistory.fragments.root} +`, + { + options: { + fetchPolicy: 'network-only', + }, + } +); + +const mapStateToProps = state => ({ + currentUser: state.auth.user, +}); + +const mapDispatchToProps = dispatch => + bindActionCreators({ showSignInDialog }, dispatch); + +export default compose( + connect(mapStateToProps, mapDispatchToProps), + withProfileQuery +)(ProfileContainer); diff --git a/client/coral-embed-stream/src/tabs/profile/containers/ProfileContainer.js b/client/coral-embed-stream/src/tabs/profile/containers/ProfileContainer.js deleted file mode 100644 index 57aa2b0fe..000000000 --- a/client/coral-embed-stream/src/tabs/profile/containers/ProfileContainer.js +++ /dev/null @@ -1,178 +0,0 @@ -import { connect } from 'react-redux'; -import { compose, gql } from 'react-apollo'; -import React, { Component } from 'react'; -import { bindActionCreators } from 'redux'; -import { withQuery } from 'coral-framework/hocs'; -import Slot from 'coral-framework/components/Slot'; -import cn from 'classnames'; -import { link } from 'coral-framework/services/pym'; -import NotLoggedIn from '../components/NotLoggedIn'; -import { Spinner } from 'coral-ui'; -import CommentHistory from '../components/CommentHistory'; - -import { showSignInDialog } from 'coral-embed-stream/src/actions/login'; -import { appendNewNodes } from 'plugin-api/beta/client/utils'; -import update from 'immutability-helper'; -import { getSlotFragmentSpreads } from 'coral-framework/utils'; - -import t from 'coral-framework/services/i18n'; - -class ProfileContainer extends Component { - componentWillReceiveProps(nextProps) { - if (!this.props.currentUser && nextProps.currentUser) { - // Refetch after login. - this.props.data.refetch(); - } - } - - loadMore = () => { - return this.props.data.fetchMore({ - query: LOAD_MORE_QUERY, - variables: { - limit: 5, - cursor: this.props.root.me.comments.endCursor, - }, - updateQuery: (previous, { fetchMoreResult: { me: { comments } } }) => { - const updated = update(previous, { - me: { - comments: { - nodes: { - $apply: nodes => appendNewNodes(nodes, comments.nodes), - }, - hasNextPage: { $set: comments.hasNextPage }, - endCursor: { $set: comments.endCursor }, - }, - }, - }); - return updated; - }, - }); - }; - - render() { - const { currentUser, showSignInDialog, root, data } = this.props; - const { me } = this.props.root; - const loading = this.props.data.loading; - - if (this.props.data.error) { - return
    {this.props.data.error.message}
    ; - } - - if (!currentUser) { - return ; - } - - if (loading || !me) { - return ; - } - - const localProfile = currentUser.profiles.find(p => p.provider === 'local'); - const emailAddress = localProfile && localProfile.id; - - return ( -
    -

    {me.username}

    - {emailAddress ?

    {emailAddress}

    : null} - -
    -

    {t('framework.my_comments')}

    -
    - {me.comments.nodes.length ? ( - - ) : ( -

    - {t('user_no_comment')} -

    - )} -
    -
    - ); - } -} - -const slots = [ - 'profileSections', - - // TODO: These Slots should be included in `talk-plugin-history` instead. - 'commentContent', - 'historyCommentTimestamp', -]; - -const CommentFragment = gql` - fragment TalkSettings_CommentConnectionFragment on CommentConnection { - nodes { - id - body - replyCount - action_summaries { - count - __typename - } - asset { - id - title - url - ${getSlotFragmentSpreads(slots, 'asset')} - } - created_at - ${getSlotFragmentSpreads(slots, 'comment')} - } - endCursor - hasNextPage - } -`; - -const LOAD_MORE_QUERY = gql` - query TalkSettings_LoadMoreComments($limit: Int, $cursor: Cursor) { - me { - comments(query: { limit: $limit, cursor: $cursor }) { - ...TalkSettings_CommentConnectionFragment - } - } - } - ${CommentFragment} -`; - -const withProfileQuery = withQuery( - gql` - query CoralEmbedStream_Profile { - me { - id - username - comments(query: {limit: 10}) { - ...TalkSettings_CommentConnectionFragment - } - } - ${getSlotFragmentSpreads(slots, 'root')} - } - ${CommentFragment} -`, - { - options: { - fetchPolicy: 'network-only', - }, - } -); - -const mapStateToProps = state => ({ - currentUser: state.auth.user, -}); - -const mapDispatchToProps = dispatch => - bindActionCreators({ showSignInDialog }, dispatch); - -export default compose( - connect(mapStateToProps, mapDispatchToProps), - withProfileQuery -)(ProfileContainer); diff --git a/client/coral-framework/services/pym.js b/client/coral-framework/services/pym.js index be81fc518..b4eb193ee 100644 --- a/client/coral-framework/services/pym.js +++ b/client/coral-framework/services/pym.js @@ -1,9 +1,5 @@ import Pym from 'pym.js'; const pym = new Pym.Child({ polling: 100 }); -export default pym; -export const link = url => e => { - e.preventDefault(); - pym.sendMessage('navigate', url); -}; +export default pym; From 0ca8b978a13ea7ab1225f8c56bb063e9ab3af51a Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 20 Feb 2018 13:21:02 +0100 Subject: [PATCH 2/4] Implement profile settings --- .eslintignore | 3 +- .gitignore | 1 + .../coral-embed-stream/src/actions/profile.js | 3 ++ .../src/components/Embed.js | 10 ++-- .../src/constants/profile.js | 2 + .../coral-embed-stream/src/reducers/index.js | 2 + .../src/reducers/profile.js | 19 ++++++++ .../src/tabs/profile/components/Profile.css | 11 +++++ .../src/tabs/profile/components/Profile.js | 47 +++++++++++++++---- .../src/tabs/profile/containers/Comment.js | 2 +- .../src/tabs/profile/containers/Profile.js | 15 +++++- plugins.default.json | 3 +- .../talk-plugin-ignore-user/client/index.js | 2 +- .../.eslintrc.json | 3 ++ .../client/.eslintrc.json | 3 ++ .../client/components/Tab.js | 8 ++++ .../client/components/TabPane.js | 21 +++++++++ .../client/containers/TabPane.js | 26 ++++++++++ .../client/index.js | 11 +++++ .../client/translations.yml | 27 +++++++++++ plugins/talk-plugin-profile-settings/index.js | 1 + 21 files changed, 200 insertions(+), 20 deletions(-) create mode 100644 client/coral-embed-stream/src/actions/profile.js create mode 100644 client/coral-embed-stream/src/constants/profile.js create mode 100644 client/coral-embed-stream/src/reducers/profile.js create mode 100644 client/coral-embed-stream/src/tabs/profile/components/Profile.css create mode 100644 plugins/talk-plugin-profile-settings/.eslintrc.json create mode 100644 plugins/talk-plugin-profile-settings/client/.eslintrc.json create mode 100644 plugins/talk-plugin-profile-settings/client/components/Tab.js create mode 100644 plugins/talk-plugin-profile-settings/client/components/TabPane.js create mode 100644 plugins/talk-plugin-profile-settings/client/containers/TabPane.js create mode 100644 plugins/talk-plugin-profile-settings/client/index.js create mode 100644 plugins/talk-plugin-profile-settings/client/translations.yml create mode 100644 plugins/talk-plugin-profile-settings/index.js diff --git a/.eslintignore b/.eslintignore index 50d3f7109..5be504ff4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -31,4 +31,5 @@ public !plugins/talk-plugin-sort-oldest !plugins/talk-plugin-subscriber !plugins/talk-plugin-toxic-comments -!plugins/talk-plugin-viewing-options \ No newline at end of file +!plugins/talk-plugin-viewing-options +!plugins/talk-plugin-profile-settings diff --git a/.gitignore b/.gitignore index a27a08f15..837bee402 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ plugins/* !plugins/talk-plugin-subscriber !plugins/talk-plugin-flag-details !plugins/talk-plugin-slack-notifications +!plugins/talk-plugin-profile-settings **/node_modules/* yarn-error.log diff --git a/client/coral-embed-stream/src/actions/profile.js b/client/coral-embed-stream/src/actions/profile.js new file mode 100644 index 000000000..4b0c8f2e2 --- /dev/null +++ b/client/coral-embed-stream/src/actions/profile.js @@ -0,0 +1,3 @@ +import * as actions from '../constants/profile'; + +export const setActiveTab = tab => ({ type: actions.SET_ACTIVE_TAB, tab }); diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js index 71ff39240..0e251e9a3 100644 --- a/client/coral-embed-stream/src/components/Embed.js +++ b/client/coral-embed-stream/src/components/Embed.js @@ -15,10 +15,6 @@ import IfSlotIsNotEmpty from 'coral-framework/components/IfSlotIsNotEmpty'; import cn from 'classnames'; export default class Embed extends React.Component { - changeTab = tab => { - this.props.setActiveTab(tab); - }; - getTabs() { const tabs = [ ( -
    -

    {username}

    - {emailAddress ?

    {emailAddress}

    : null} +const Profile = ({ + username, + emailAddress, + data, + root, + activeTab, + setActiveTab, +}) => ( +
    +
    +

    {username}

    + {emailAddress ?

    {emailAddress}

    : null} +
    -
    -

    {t('framework.my_comments')}

    - + + {t('framework.my_comments')} + , + ]} + tabPanes={[ + + + , + ]} + sub + />
    ); @@ -21,6 +50,8 @@ Profile.propTypes = { emailAddress: PropTypes.string, data: PropTypes.object, root: PropTypes.object, + activeTab: PropTypes.string.isRequired, + setActiveTab: PropTypes.func.isRequired, }; export default Profile; diff --git a/client/coral-embed-stream/src/tabs/profile/containers/Comment.js b/client/coral-embed-stream/src/tabs/profile/containers/Comment.js index 7406d4c5e..b8fb7fad8 100644 --- a/client/coral-embed-stream/src/tabs/profile/containers/Comment.js +++ b/client/coral-embed-stream/src/tabs/profile/containers/Comment.js @@ -7,7 +7,7 @@ const slots = ['commentContent', 'historyCommentTimestamp']; const withCommentFragments = withFragments({ comment: gql` - fragment TalkEmbedStream_Comment_Fragment on Comment { + fragment TalkEmbedStream_ProfileComment_comment on Comment { id body replyCount diff --git a/client/coral-embed-stream/src/tabs/profile/containers/Profile.js b/client/coral-embed-stream/src/tabs/profile/containers/Profile.js index 2fc768535..82a0a49eb 100644 --- a/client/coral-embed-stream/src/tabs/profile/containers/Profile.js +++ b/client/coral-embed-stream/src/tabs/profile/containers/Profile.js @@ -11,6 +11,7 @@ import CommentHistory from './CommentHistory'; import { getDefinitionName } from 'coral-framework/utils'; import { showSignInDialog } from 'coral-embed-stream/src/actions/login'; +import { setActiveTab } from '../../../actions/profile'; import { getSlotFragmentSpreads } from 'coral-framework/utils'; class ProfileContainer extends Component { @@ -47,6 +48,8 @@ class ProfileContainer extends Component { emailAddress={emailAddress} data={data} root={root} + activeTab={this.props.activeTab} + setActiveTab={this.props.setActiveTab} /> ); } @@ -57,9 +60,16 @@ ProfileContainer.propTypes = { root: PropTypes.object, currentUser: PropTypes.object, showSignInDialog: PropTypes.func, + activeTab: PropTypes.string.isRequired, + setActiveTab: PropTypes.func.isRequired, }; -const slots = ['profileSections']; +const slots = [ + 'profileSections', + 'profileTabs', + 'profileTabsPrepend', + 'profileTabPanes', +]; const withProfileQuery = withQuery( gql` @@ -82,10 +92,11 @@ const withProfileQuery = withQuery( const mapStateToProps = state => ({ currentUser: state.auth.user, + activeTab: state.profile.activeTab, }); const mapDispatchToProps = dispatch => - bindActionCreators({ showSignInDialog }, dispatch); + bindActionCreators({ showSignInDialog, setActiveTab }, dispatch); export default compose( connect(mapStateToProps, mapDispatchToProps), diff --git a/plugins.default.json b/plugins.default.json index 066c94478..b54c6a54c 100644 --- a/plugins.default.json +++ b/plugins.default.json @@ -21,6 +21,7 @@ "talk-plugin-sort-most-respected", "talk-plugin-sort-newest", "talk-plugin-sort-oldest", - "talk-plugin-viewing-options" + "talk-plugin-viewing-options", + "talk-plugin-profile-settings" ] } diff --git a/plugins/talk-plugin-ignore-user/client/index.js b/plugins/talk-plugin-ignore-user/client/index.js index 3284915db..a7cb6c886 100644 --- a/plugins/talk-plugin-ignore-user/client/index.js +++ b/plugins/talk-plugin-ignore-user/client/index.js @@ -8,7 +8,7 @@ export default { slots: { authorMenuActions: [IgnoreUserAction], ignoreUserConfirmation: [IgnoreUserConfirmation], - profileSections: [IgnoredUserSection], + profileSettings: [IgnoredUserSection], }, translations, mutations: { diff --git a/plugins/talk-plugin-profile-settings/.eslintrc.json b/plugins/talk-plugin-profile-settings/.eslintrc.json new file mode 100644 index 000000000..78f7c2397 --- /dev/null +++ b/plugins/talk-plugin-profile-settings/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@coralproject/eslint-config-talk" +} diff --git a/plugins/talk-plugin-profile-settings/client/.eslintrc.json b/plugins/talk-plugin-profile-settings/client/.eslintrc.json new file mode 100644 index 000000000..c8a6db18a --- /dev/null +++ b/plugins/talk-plugin-profile-settings/client/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@coralproject/eslint-config-talk/client" +} diff --git a/plugins/talk-plugin-profile-settings/client/components/Tab.js b/plugins/talk-plugin-profile-settings/client/components/Tab.js new file mode 100644 index 000000000..86df0e8d1 --- /dev/null +++ b/plugins/talk-plugin-profile-settings/client/components/Tab.js @@ -0,0 +1,8 @@ +import React from 'react'; +import { t } from 'plugin-api/beta/client/services'; + +const Tab = () => { + return {t('talk-plugin-profile-settings.tab')}; +}; + +export default Tab; diff --git a/plugins/talk-plugin-profile-settings/client/components/TabPane.js b/plugins/talk-plugin-profile-settings/client/components/TabPane.js new file mode 100644 index 000000000..c0347a95c --- /dev/null +++ b/plugins/talk-plugin-profile-settings/client/components/TabPane.js @@ -0,0 +1,21 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Slot } from 'plugin-api/beta/client/components'; + +class TabPane extends React.Component { + render() { + const { data, root } = this.props; + return ( +
    + +
    + ); + } +} + +TabPane.propTypes = { + data: PropTypes.object, + root: PropTypes.object, +}; + +export default TabPane; diff --git a/plugins/talk-plugin-profile-settings/client/containers/TabPane.js b/plugins/talk-plugin-profile-settings/client/containers/TabPane.js new file mode 100644 index 000000000..6384c7160 --- /dev/null +++ b/plugins/talk-plugin-profile-settings/client/containers/TabPane.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { compose, gql } from 'react-apollo'; +import TabPane from '../components/TabPane'; +import { withFragments } from 'plugin-api/beta/client/hocs'; +import { getSlotFragmentSpreads } from 'plugin-api/beta/client/utils'; + +const slots = ['profileSettings']; + +class TabPaneContainer extends React.Component { + render() { + return ; + } +} + +const enhance = compose( + withFragments({ + root: gql` + fragment TalkProfileSettings_TabPane_root on RootQuery { + __typename + ${getSlotFragmentSpreads(slots, 'root')} + } + `, + }) +); + +export default enhance(TabPaneContainer); diff --git a/plugins/talk-plugin-profile-settings/client/index.js b/plugins/talk-plugin-profile-settings/client/index.js new file mode 100644 index 000000000..00e37a0f1 --- /dev/null +++ b/plugins/talk-plugin-profile-settings/client/index.js @@ -0,0 +1,11 @@ +import Tab from './components/Tab'; +import TabPane from './containers/TabPane'; +import translations from './translations.yml'; + +export default { + slots: { + profileTabs: [Tab], + profileTabPanes: [TabPane], + }, + translations, +}; diff --git a/plugins/talk-plugin-profile-settings/client/translations.yml b/plugins/talk-plugin-profile-settings/client/translations.yml new file mode 100644 index 000000000..cd8edb415 --- /dev/null +++ b/plugins/talk-plugin-profile-settings/client/translations.yml @@ -0,0 +1,27 @@ +en: + talk-plugin-profile-settings: + tab: Settings +de: + talk-plugin-profile-settings: + tab: Einstellungen +es: + talk-plugin-profile-settings: + tab: Configuración +fr: + talk-plugin-profile-settings: + tab: Paramètres +nl_NL: + talk-plugin-profile-settings: + tab: Instellingen +da: + talk-plugin-profile-settings: + tab: Indstillinger +pt_PR: + talk-plugin-profile-settings: + tab: Configurações +zh_TW: + talk-plugin-profile-settings: + tab: 設置 +zh_CN: + talk-plugin-profile-settings: + tab: 设置 diff --git a/plugins/talk-plugin-profile-settings/index.js b/plugins/talk-plugin-profile-settings/index.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/plugins/talk-plugin-profile-settings/index.js @@ -0,0 +1 @@ +module.exports = {}; From 7dd63dc81242e665586bbcf5cce9607a2405c83d Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Thu, 22 Feb 2018 10:38:18 +0100 Subject: [PATCH 3/4] Fix CI --- .../tabs/profile/components/CommentHistory.js | 2 +- plugins.json.tmp | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 plugins.json.tmp diff --git a/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js b/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js index f16e8a119..39f3bfd04 100644 --- a/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js +++ b/client/coral-embed-stream/src/tabs/profile/components/CommentHistory.js @@ -23,7 +23,7 @@ class CommentHistory extends React.Component { render() { const { navigate, comments, data, root } = this.props; return ( -
    +
    {comments.nodes.map((comment, i) => { return ( diff --git a/plugins.json.tmp b/plugins.json.tmp new file mode 100644 index 000000000..f8fa64268 --- /dev/null +++ b/plugins.json.tmp @@ -0,0 +1,33 @@ +{ + "server": [ + "talk-plugin-auth", + "talk-plugin-featured-comments", + "talk-plugin-offtopic", + "talk-plugin-respect", + "talk-plugin-toxic-comments", + "talk-plugin-notifications", + "talk-plugin-notifications-category-reply" + ], + "client": [ + "talk-plugin-auth", + "talk-plugin-author-menu", + "talk-plugin-comment-content", + "talk-plugin-featured-comments", + "talk-plugin-flag-details", + "talk-plugin-member-since", + "talk-plugin-moderation-actions", + "talk-plugin-offtopic", + "talk-plugin-permalink", + "talk-plugin-respect", + "talk-plugin-sort-most-replied", + "talk-plugin-sort-most-respected", + "talk-plugin-sort-newest", + "talk-plugin-sort-oldest", + "talk-plugin-viewing-options", + "talk-plugin-toxic-comments", + "talk-plugin-profile-settings", + "talk-plugin-notifications", + "talk-plugin-notifications-category-reply", + "talk-plugin-ignore-user" + ] +} From 4d943629d97bcfacefa521f4ad61764af7f514d1 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Thu, 22 Feb 2018 10:47:13 +0100 Subject: [PATCH 4/4] Rm accident added file --- plugins.json.tmp | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 plugins.json.tmp diff --git a/plugins.json.tmp b/plugins.json.tmp deleted file mode 100644 index f8fa64268..000000000 --- a/plugins.json.tmp +++ /dev/null @@ -1,33 +0,0 @@ -{ - "server": [ - "talk-plugin-auth", - "talk-plugin-featured-comments", - "talk-plugin-offtopic", - "talk-plugin-respect", - "talk-plugin-toxic-comments", - "talk-plugin-notifications", - "talk-plugin-notifications-category-reply" - ], - "client": [ - "talk-plugin-auth", - "talk-plugin-author-menu", - "talk-plugin-comment-content", - "talk-plugin-featured-comments", - "talk-plugin-flag-details", - "talk-plugin-member-since", - "talk-plugin-moderation-actions", - "talk-plugin-offtopic", - "talk-plugin-permalink", - "talk-plugin-respect", - "talk-plugin-sort-most-replied", - "talk-plugin-sort-most-respected", - "talk-plugin-sort-newest", - "talk-plugin-sort-oldest", - "talk-plugin-viewing-options", - "talk-plugin-toxic-comments", - "talk-plugin-profile-settings", - "talk-plugin-notifications", - "talk-plugin-notifications-category-reply", - "talk-plugin-ignore-user" - ] -}