From 692d92f645e141c27e9620b7d2c08b7f71e4baf9 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Fri, 1 Sep 2017 22:20:49 +0700 Subject: [PATCH 01/20] Implement talk-plugin-author-menu --- .eslintignore | 1 + .gitignore | 1 + .../talk-plugin-author-menu/client/.babelrc | 14 ++++ .../client/.eslintrc.json | 23 ++++++ .../talk-plugin-author-menu/client/actions.js | 10 +++ .../client/components/AuthorName.css | 13 +++ .../client/components/AuthorName.js | 30 +++++++ .../client/components/Menu.css | 37 +++++++++ .../client/components/Menu.js | 18 +++++ .../client/constants.js | 5 ++ .../client/containers/AuthorName.js | 79 +++++++++++++++++++ .../talk-plugin-author-menu/client/index.js | 11 +++ .../talk-plugin-author-menu/client/reducer.js | 22 ++++++ .../client/translations.yml | 4 + plugins/talk-plugin-author-menu/index.js | 1 + plugins/talk-plugin-like/client/index.js | 2 +- 16 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 plugins/talk-plugin-author-menu/client/.babelrc create mode 100644 plugins/talk-plugin-author-menu/client/.eslintrc.json create mode 100644 plugins/talk-plugin-author-menu/client/actions.js create mode 100644 plugins/talk-plugin-author-menu/client/components/AuthorName.css create mode 100644 plugins/talk-plugin-author-menu/client/components/AuthorName.js create mode 100644 plugins/talk-plugin-author-menu/client/components/Menu.css create mode 100644 plugins/talk-plugin-author-menu/client/components/Menu.js create mode 100644 plugins/talk-plugin-author-menu/client/constants.js create mode 100644 plugins/talk-plugin-author-menu/client/containers/AuthorName.js create mode 100644 plugins/talk-plugin-author-menu/client/index.js create mode 100644 plugins/talk-plugin-author-menu/client/reducer.js create mode 100644 plugins/talk-plugin-author-menu/client/translations.yml create mode 100644 plugins/talk-plugin-author-menu/index.js diff --git a/.eslintignore b/.eslintignore index e09212b62..b9523387a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -19,5 +19,6 @@ plugins/* !plugins/talk-plugin-sort-most-liked !plugins/talk-plugin-sort-most-loved !plugins/talk-plugin-sort-most-respected +!plugins/talk-plugin-author-menu node_modules diff --git a/.gitignore b/.gitignore index 3fdb05c89..99eac3ade 100644 --- a/.gitignore +++ b/.gitignore @@ -35,5 +35,6 @@ plugins/* !plugins/talk-plugin-sort-most-liked !plugins/talk-plugin-sort-most-loved !plugins/talk-plugin-sort-most-respected +!plugins/talk-plugin-author-menu **/node_modules/* diff --git a/plugins/talk-plugin-author-menu/client/.babelrc b/plugins/talk-plugin-author-menu/client/.babelrc new file mode 100644 index 000000000..60be246eb --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/.babelrc @@ -0,0 +1,14 @@ +{ + "presets": [ + "es2015" + ], + "plugins": [ + "add-module-exports", + "transform-class-properties", + "transform-decorators-legacy", + "transform-object-assign", + "transform-object-rest-spread", + "transform-async-to-generator", + "transform-react-jsx" + ] +} \ No newline at end of file diff --git a/plugins/talk-plugin-author-menu/client/.eslintrc.json b/plugins/talk-plugin-author-menu/client/.eslintrc.json new file mode 100644 index 000000000..9fe56bd14 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "env": { + "browser": true, + "es6": true, + "mocha": true + }, + "parserOptions": { + "sourceType": "module", + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + } + }, + "parser": "babel-eslint", + "plugins": [ + "react" + ], + "rules": { + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", + "no-console": ["warn", { "allow": ["warn", "error"] }] + } +} diff --git a/plugins/talk-plugin-author-menu/client/actions.js b/plugins/talk-plugin-author-menu/client/actions.js new file mode 100644 index 000000000..0a806749d --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/actions.js @@ -0,0 +1,10 @@ +import {SET_CONTENT_SLOT, RESET_CONTENT_SLOT} from './constants'; + +export const setContentSlot = (slot) => ({ + type: SET_CONTENT_SLOT, + slot, +}); + +export const resetContentSlot = () => ({ + type: RESET_CONTENT_SLOT, +}); diff --git a/plugins/talk-plugin-author-menu/client/components/AuthorName.css b/plugins/talk-plugin-author-menu/client/components/AuthorName.css new file mode 100644 index 000000000..386d7cb45 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/components/AuthorName.css @@ -0,0 +1,13 @@ +.root { + display: inline-block; + position: relative; +} + +.button { + composes: buttonReset from "coral-framework/styles/reset.css"; +} + +.name { + font-weight: bold; +} + diff --git a/plugins/talk-plugin-author-menu/client/components/AuthorName.js b/plugins/talk-plugin-author-menu/client/components/AuthorName.js new file mode 100644 index 000000000..d6e6c66d1 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/components/AuthorName.js @@ -0,0 +1,30 @@ +import React from 'react'; +import Menu from './Menu'; +import styles from './AuthorName.css'; +import {ClickOutside} from 'plugin-api/beta/client/components'; + +export default ({data, root, asset, comment, contentSlot, menuVisible, toggleMenu, hideMenu}) => { + return ( + +
+ + {menuVisible && + + } +
+
+ ); +}; diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.css b/plugins/talk-plugin-author-menu/client/components/Menu.css new file mode 100644 index 000000000..6ff52d81e --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/components/Menu.css @@ -0,0 +1,37 @@ + +.menu { + background-color: white; + border: solid 1px #999; + border-radius: 3px; + padding: 10px; + position: absolute; + -webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2); + box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2); + z-index: 10; + top: 26px; + left: 0px; + min-width: 20px; + text-align: left; + color: #616161; +} + +.menu::before{ + content: ''; + border: 10px solid transparent; + border-top-color: #999; + position: absolute; + left: 6px; + top: -21px; + transform: rotate(180deg); +} + +.menu::after{ + content: ''; + border: 10px solid transparent; + border-top-color: white; + position: absolute; + left: 6px; + top: -20px; + transform: rotate(180deg); +} + diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.js b/plugins/talk-plugin-author-menu/client/components/Menu.js new file mode 100644 index 000000000..b3f6e2888 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/components/Menu.js @@ -0,0 +1,18 @@ +import React from 'react'; +import styles from './Menu.css'; +import {Slot} from 'plugin-api/beta/client/components'; + +export default ({data, root, asset, comment}) => ( +
+ + +
+); diff --git a/plugins/talk-plugin-author-menu/client/constants.js b/plugins/talk-plugin-author-menu/client/constants.js new file mode 100644 index 000000000..a11de608a --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/constants.js @@ -0,0 +1,5 @@ +const prefix = 'TALK_AUTHOR_MENU'; + +export const SET_CONTENT_SLOT = `${prefix}_SET_CONTENT_SLOT`; +export const RESET_CONTENT_SLOT = `${prefix}_RESET_CONTENT_SLOT`; + diff --git a/plugins/talk-plugin-author-menu/client/containers/AuthorName.js b/plugins/talk-plugin-author-menu/client/containers/AuthorName.js new file mode 100644 index 000000000..9551e38d6 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/containers/AuthorName.js @@ -0,0 +1,79 @@ +import React from 'react'; +import {connect, withFragments} from 'plugin-api/beta/client/hocs'; +import {bindActionCreators} from 'redux'; +import AuthorName from '../components/AuthorName'; +import {setContentSlot, resetContentSlot} from '../actions'; +import {compose, gql} from 'react-apollo'; +import {getSlotFragmentSpreads} from 'plugin-api/beta/client/utils'; + +class AuthorNameContainer extends React.Component { + state = { + menuVisible: false + }; + + toggleMenu = () => { + this.setState({ + menuVisible: !this.state.menuVisible, + }); + } + + hideMenu = () => { + if (this.state.menuVisible) { + this.setState({ + menuVisible: false + }); + } + } + + render() { + return ; + } +} + +const slots = [ + 'authorMenuInfos', + 'authorMenuActions', +]; + +const mapStateToProps = ({talkPluginAuthorMenu: state}) => ({ + contentSlot: state.contentSlot, +}); + +const mapDispatchToProps = (dispatch) => + bindActionCreators({setContentSlot, resetContentSlot}, dispatch); + +const withAuthorNameFragments = withFragments({ + root: gql` + fragment TalkAuthorMenu_AuthorName_root on RootQuery { + __typename + ${getSlotFragmentSpreads(slots, 'root')} + }`, + asset: gql` + fragment TalkAuthorMenu_AuthorName_asset on Asset { + __typename + ${getSlotFragmentSpreads(slots, 'asset')} + }`, + comment: gql` + fragment TalkAuthorMenu_AuthorName_comment on Comment { + __typename + user { + username + } + ${getSlotFragmentSpreads(slots, 'comment')} + }`, +}); + +const enhance = compose( + connect(mapStateToProps, mapDispatchToProps), + withAuthorNameFragments, +); + +export default enhance(AuthorNameContainer); diff --git a/plugins/talk-plugin-author-menu/client/index.js b/plugins/talk-plugin-author-menu/client/index.js new file mode 100644 index 000000000..a98a15822 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/index.js @@ -0,0 +1,11 @@ +import AuthorName from './containers/AuthorName'; +import reducer from './reducer'; +import translations from './translations.yml'; + +export default { + reducer, + slots: { + commentAuthorName: [AuthorName] + }, + translations +}; diff --git a/plugins/talk-plugin-author-menu/client/reducer.js b/plugins/talk-plugin-author-menu/client/reducer.js new file mode 100644 index 000000000..4f04d07ed --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/reducer.js @@ -0,0 +1,22 @@ +import {SET_CONTENT_SLOT, RESET_CONTENT_SLOT} from './constants'; + +const initialState = { + contentSlot: null, +}; + +export default function reducer(state = initialState, action) { + switch (action.type) { + case SET_CONTENT_SLOT: + return { + ...state, + contentSlot: action.slot, + }; + case RESET_CONTENT_SLOT: + return { + ...state, + contentSlot: initialState.contentSlot, + }; + default : + return state; + } +} diff --git a/plugins/talk-plugin-author-menu/client/translations.yml b/plugins/talk-plugin-author-menu/client/translations.yml new file mode 100644 index 000000000..adac91ad4 --- /dev/null +++ b/plugins/talk-plugin-author-menu/client/translations.yml @@ -0,0 +1,4 @@ +en: + talk-plugin-author-menu: +es: + talk-plugin-author-menu: diff --git a/plugins/talk-plugin-author-menu/index.js b/plugins/talk-plugin-author-menu/index.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/plugins/talk-plugin-author-menu/index.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/plugins/talk-plugin-like/client/index.js b/plugins/talk-plugin-like/client/index.js index 68b7a2c46..aaea3aaf4 100644 --- a/plugins/talk-plugin-like/client/index.js +++ b/plugins/talk-plugin-like/client/index.js @@ -5,5 +5,5 @@ export default { translations, slots: { commentReactions: [LikeButton] - } + }, }; From 7c339aa510bcd77b8e807cfe6c52a942ee4dae0f Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Fri, 1 Sep 2017 22:25:26 +0700 Subject: [PATCH 02/20] Render contentSlot if set --- .../client/components/Menu.js | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.js b/plugins/talk-plugin-author-menu/client/components/Menu.js index b3f6e2888..fdedf6594 100644 --- a/plugins/talk-plugin-author-menu/client/components/Menu.js +++ b/plugins/talk-plugin-author-menu/client/components/Menu.js @@ -2,17 +2,29 @@ import React from 'react'; import styles from './Menu.css'; import {Slot} from 'plugin-api/beta/client/components'; -export default ({data, root, asset, comment}) => ( -
- - -
-); +export default ({data, root, asset, comment, contentSlot}) => { + if (contentSlot) { + return ( + + ); + } + + return ( +
+ + +
+ ); +}; From 9c2ea693b91b8398f12c9e8d993d6b0808e61d61 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Fri, 1 Sep 2017 22:29:30 +0700 Subject: [PATCH 03/20] Add hover styles --- .../talk-plugin-author-menu/client/components/AuthorName.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/talk-plugin-author-menu/client/components/AuthorName.css b/plugins/talk-plugin-author-menu/client/components/AuthorName.css index 386d7cb45..d9a8bdd71 100644 --- a/plugins/talk-plugin-author-menu/client/components/AuthorName.css +++ b/plugins/talk-plugin-author-menu/client/components/AuthorName.css @@ -5,6 +5,9 @@ .button { composes: buttonReset from "coral-framework/styles/reset.css"; + &:hover { + text-decoration: underline; + } } .name { From c07eaf0edbddc2a132818bec042ffe5dccaf2a48 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Fri, 1 Sep 2017 23:15:00 +0700 Subject: [PATCH 04/20] Add member since --- .eslintignore | 1 + .gitignore | 1 + package.json | 1 + .../client/components/Menu.css | 2 +- .../talk-plugin-member-since/client/.babelrc | 14 + .../client/.eslintrc.json | 23 ++ .../client/components/MemberSinceInfo.css | 16 ++ .../client/components/MemberSinceInfo.js | 14 + .../client/containers/MemberSinceInfo.js | 28 ++ .../talk-plugin-member-since/client/index.js | 9 + .../client/translations.yml | 6 + plugins/talk-plugin-member-since/index.js | 1 + yarn.lock | 250 +++--------------- 13 files changed, 150 insertions(+), 216 deletions(-) create mode 100644 plugins/talk-plugin-member-since/client/.babelrc create mode 100644 plugins/talk-plugin-member-since/client/.eslintrc.json create mode 100644 plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css create mode 100644 plugins/talk-plugin-member-since/client/components/MemberSinceInfo.js create mode 100644 plugins/talk-plugin-member-since/client/containers/MemberSinceInfo.js create mode 100644 plugins/talk-plugin-member-since/client/index.js create mode 100644 plugins/talk-plugin-member-since/client/translations.yml create mode 100644 plugins/talk-plugin-member-since/index.js diff --git a/.eslintignore b/.eslintignore index b9523387a..688e285c5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -20,5 +20,6 @@ plugins/* !plugins/talk-plugin-sort-most-loved !plugins/talk-plugin-sort-most-respected !plugins/talk-plugin-author-menu +!plugins/talk-plugin-member-since node_modules diff --git a/.gitignore b/.gitignore index 99eac3ade..f8be44f20 100644 --- a/.gitignore +++ b/.gitignore @@ -36,5 +36,6 @@ plugins/* !plugins/talk-plugin-sort-most-loved !plugins/talk-plugin-sort-most-respected !plugins/talk-plugin-author-menu +!plugins/talk-plugin-member-since **/node_modules/* diff --git a/package.json b/package.json index a5127f6ac..8c45239e3 100644 --- a/package.json +++ b/package.json @@ -130,6 +130,7 @@ "material-design-lite": "^1.2.1", "metascraper": "^1.0.7", "minimist": "^1.2.0", + "moment": "^2.18.1", "mongoose": "^4.11.7", "morgan": "^1.8.2", "ms": "^2.0.0", diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.css b/plugins/talk-plugin-author-menu/client/components/Menu.css index 6ff52d81e..86befe54a 100644 --- a/plugins/talk-plugin-author-menu/client/components/Menu.css +++ b/plugins/talk-plugin-author-menu/client/components/Menu.css @@ -7,7 +7,7 @@ position: absolute; -webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2); box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2); - z-index: 10; + z-index: 9; top: 26px; left: 0px; min-width: 20px; diff --git a/plugins/talk-plugin-member-since/client/.babelrc b/plugins/talk-plugin-member-since/client/.babelrc new file mode 100644 index 000000000..60be246eb --- /dev/null +++ b/plugins/talk-plugin-member-since/client/.babelrc @@ -0,0 +1,14 @@ +{ + "presets": [ + "es2015" + ], + "plugins": [ + "add-module-exports", + "transform-class-properties", + "transform-decorators-legacy", + "transform-object-assign", + "transform-object-rest-spread", + "transform-async-to-generator", + "transform-react-jsx" + ] +} \ No newline at end of file diff --git a/plugins/talk-plugin-member-since/client/.eslintrc.json b/plugins/talk-plugin-member-since/client/.eslintrc.json new file mode 100644 index 000000000..9fe56bd14 --- /dev/null +++ b/plugins/talk-plugin-member-since/client/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "env": { + "browser": true, + "es6": true, + "mocha": true + }, + "parserOptions": { + "sourceType": "module", + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + } + }, + "parser": "babel-eslint", + "plugins": [ + "react" + ], + "rules": { + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", + "no-console": ["warn", { "allow": ["warn", "error"] }] + } +} diff --git a/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css b/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css new file mode 100644 index 000000000..cefd32d40 --- /dev/null +++ b/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css @@ -0,0 +1,16 @@ +.root { + white-space: nowrap; +} + +.memberSince { + color: #484747; + margin-left: 4px; + letter-spacing: 0.2px; + font-size: 0.9em; + vertical-align: middle; +} + +.icon { + font-size: 1.4em; + vertical-align: middle; +} diff --git a/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.js b/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.js new file mode 100644 index 000000000..4263225b6 --- /dev/null +++ b/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.js @@ -0,0 +1,14 @@ +import React from 'react'; +import styles from './MemberSinceInfo.css'; +import {t} from 'plugin-api/beta/client/services'; +import {Icon} from 'plugin-api/beta/client/components/ui'; +import moment from 'moment'; + +export default ({memberSinceDate}) => ( +
+ + + {t('talk-plugin-member-since.member_since')}: {moment(new Date(memberSinceDate)).format('MMM DD, YYYY')} + +
+); diff --git a/plugins/talk-plugin-member-since/client/containers/MemberSinceInfo.js b/plugins/talk-plugin-member-since/client/containers/MemberSinceInfo.js new file mode 100644 index 000000000..186e9c8c1 --- /dev/null +++ b/plugins/talk-plugin-member-since/client/containers/MemberSinceInfo.js @@ -0,0 +1,28 @@ +import React from 'react'; +import MemberSinceInfo from '../components/MemberSinceInfo'; +import {compose, gql} from 'react-apollo'; +import {withFragments} from 'plugin-api/beta/client/hocs'; + +class MemberSinceInfoContainer extends React.Component { + render() { + return ; + } +} + +const withMemberSinceInfoFragments = withFragments({ + comment: gql` + fragment TalkAuthorMenu_MemberSinceInfo_comment on Comment { + user { + username + created_at + } + }`, +}); + +const enhance = compose( + withMemberSinceInfoFragments, +); + +export default enhance(MemberSinceInfoContainer); diff --git a/plugins/talk-plugin-member-since/client/index.js b/plugins/talk-plugin-member-since/client/index.js new file mode 100644 index 000000000..cfb60d867 --- /dev/null +++ b/plugins/talk-plugin-member-since/client/index.js @@ -0,0 +1,9 @@ +import MemberSinceInfo from './containers/MemberSinceInfo'; +import translations from './translations.yml'; + +export default { + slots: { + authorMenuInfos: [MemberSinceInfo] + }, + translations +}; diff --git a/plugins/talk-plugin-member-since/client/translations.yml b/plugins/talk-plugin-member-since/client/translations.yml new file mode 100644 index 000000000..1329974d7 --- /dev/null +++ b/plugins/talk-plugin-member-since/client/translations.yml @@ -0,0 +1,6 @@ +en: + talk-plugin-member-since: + member_since: "Member Since" +es: + talk-plugin-member-since: + member_since: "Miembro desde" diff --git a/plugins/talk-plugin-member-since/index.js b/plugins/talk-plugin-member-since/index.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/plugins/talk-plugin-member-since/index.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/yarn.lock b/yarn.lock index d55aa9745..1ca8acdbb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -63,20 +63,13 @@ abbrev@1, abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" -accepts@^1.3.4: +accepts@^1.3.4, accepts@~1.3.3: version "1.3.4" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" dependencies: mime-types "~2.1.16" negotiator "0.6.1" -accepts@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" - dependencies: - mime-types "~2.1.11" - negotiator "0.6.1" - acorn-dynamic-import@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" @@ -356,18 +349,12 @@ async@2.1.4: dependencies: lodash "^4.14.0" -async@2.4.1: +async@2.4.1, async@^2.1.2, async@^2.1.4: version "2.4.1" resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" dependencies: lodash "^4.14.0" -async@^2.1.2, async@^2.1.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" - dependencies: - lodash "^4.14.0" - async@~0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" @@ -416,15 +403,7 @@ babel-cli@^6.26.0: optionalDependencies: chokidar "^1.6.1" -babel-code-frame@^6.11.0, babel-code-frame@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" - dependencies: - chalk "^1.1.0" - esutils "^2.0.2" - js-tokens "^3.0.0" - -babel-code-frame@^6.26.0: +babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -465,20 +444,7 @@ babel-eslint@^7.2.1: babel-types "^6.23.0" babylon "^6.17.0" -babel-generator@^6.18.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - -babel-generator@^6.26.0: +babel-generator@^6.18.0, babel-generator@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" dependencies: @@ -956,31 +922,14 @@ babel-register@^6.26.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.6.1: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - -babel-runtime@^6.26.0: +babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.6.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.3.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" - lodash "^4.2.0" - -babel-template@^6.26.0: +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.3.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" dependencies: @@ -990,21 +939,7 @@ babel-template@^6.26.0: babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" - dependencies: - babel-code-frame "^6.22.0" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-traverse@^6.26.0: +babel-traverse@^6.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" dependencies: @@ -1018,16 +953,7 @@ babel-traverse@^6.26.0: invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" - dependencies: - babel-runtime "^6.22.0" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babel-types@^6.26.0: +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" dependencies: @@ -1036,11 +962,7 @@ babel-types@^6.26.0: lodash "^4.17.4" to-fast-properties "^1.0.3" -babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0, babylon@^6.17.0: - version "6.17.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.0.tgz#37da948878488b9c4e3c4038893fa3314b3fc932" - -babylon@^6.18.0: +babylon@^6.13.0, babylon@^6.17.0, babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -1056,7 +978,7 @@ balanced-match@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.2.1.tgz#7bc658b4bed61eee424ad74f75f5c3e2c4df3cc7" -balanced-match@^0.4.1, balanced-match@^0.4.2: +balanced-match@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" @@ -1112,7 +1034,7 @@ bluebird@2.9.24: version "2.9.24" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.9.24.tgz#14a2e75f0548323dc35aa440d92007ca154e967c" -bluebird@3.5.0, bluebird@^3.3.4: +bluebird@3.5.0, bluebird@^3.3.4, bluebird@^3.4.6: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" @@ -1120,30 +1042,11 @@ bluebird@^2.10.2: version "2.11.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" -bluebird@^3.4.6: - version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" -body-parser@^1.12.2: - version "1.17.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.1.tgz#75b3bc98ddd6e7e0d8ffe750dfaca5c66993fa47" - dependencies: - bytes "2.4.0" - content-type "~1.0.2" - debug "2.6.1" - depd "~1.1.0" - http-errors "~1.6.1" - iconv-lite "0.4.15" - on-finished "~2.3.0" - qs "6.4.0" - raw-body "~2.2.0" - type-is "~1.6.14" - -body-parser@^1.17.2: +body-parser@^1.12.2, body-parser@^1.17.2: version "1.17.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee" dependencies: @@ -1172,13 +1075,6 @@ bowser@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.7.2.tgz#b94cc6925ba6b5e07c421a58e601ce4611264572" -brace-expansion@^1.0.0: - version "1.1.7" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" - dependencies: - balanced-match "^0.4.1" - concat-map "0.0.1" - brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -1394,7 +1290,7 @@ chalk@2.0.1: escape-string-regexp "^1.0.5" supports-color "^4.0.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1867,11 +1763,7 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" - -core-js@^2.5.0: +core-js@^2.4.0, core-js@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.0.tgz#569c050918be6486b3837552028ae0466b717086" @@ -2131,9 +2023,9 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@*: - version "3.0.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.0.tgz#1d2feae53349047b08b264ec41906ba17a8516e4" +debug@*, debug@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64" dependencies: ms "2.0.0" @@ -2143,12 +2035,6 @@ debug@2.6.0: dependencies: ms "0.7.2" -debug@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" - dependencies: - ms "0.7.2" - debug@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e" @@ -2161,12 +2047,6 @@ debug@2.6.8, debug@^2.2.0, debug@^2.6.8: dependencies: ms "2.0.0" -debug@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64" - dependencies: - ms "2.0.0" - debug@~0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" @@ -3200,7 +3080,7 @@ glob@7.0.x: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: +glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" dependencies: @@ -3211,7 +3091,7 @@ glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.1.2, glob@^7.1.2: +glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -3242,10 +3122,6 @@ glob@^6.0.4: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.0.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" - globals@^9.17.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -3372,15 +3248,7 @@ graphql-server-module-graphiql@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/graphql-server-module-graphiql/-/graphql-server-module-graphiql-0.6.0.tgz#e37634b05f000731981e8ed13103f9a5861e5da0" -graphql-subscriptions@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.4.4.tgz#39cff32d08dd3c990113864bab77154403727e9b" - dependencies: - "@types/graphql" "^0.9.1" - es6-promise "^4.0.5" - iterall "^1.1.1" - -graphql-subscriptions@^0.4.3: +graphql-subscriptions@^0.4.2, graphql-subscriptions@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-0.4.3.tgz#2aed6ba87551cc747742b793497ff24b22991867" dependencies: @@ -4240,22 +4108,18 @@ js-stringify@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" -js-tokens@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" - -js-tokens@^3.0.2: +js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@3.x, js-yaml@^3.4.3, js-yaml@^3.5.2, js-yaml@^3.7.0: +js-yaml@3.x, js-yaml@^3.5.2: version "3.8.3" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766" dependencies: argparse "^1.0.7" esprima "^3.1.1" -js-yaml@^3.9.1: +js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.9.1: version "3.9.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" dependencies: @@ -4318,11 +4182,7 @@ jshint@^2.8.0: shelljs "0.3.x" strip-json-comments "1.0.x" -json-loader@^0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de" - -json-loader@^0.5.7: +json-loader@^0.5.4, json-loader@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" @@ -4954,15 +4814,11 @@ mime-db@~1.12.0: version "1.12.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.12.0.tgz#3d0c63180f458eb10d325aaa37d7c58ae312e9d7" -mime-db@~1.27.0: - version "1.27.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" - -mime-types@^2.1.10, mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.15, mime-types@~2.1.7: - version "2.1.15" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" +mime-types@^2.1.10, mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.7: + version "2.1.16" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.16.tgz#2b858a52e5ecd516db897ac2be87487830698e23" dependencies: - mime-db "~1.27.0" + mime-db "~1.29.0" mime-types@~2.0.3: version "2.0.14" @@ -4970,12 +4826,6 @@ mime-types@~2.0.3: dependencies: mime-db "~1.12.0" -mime-types@~2.1.16: - version "2.1.16" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.16.tgz#2b858a52e5ecd516db897ac2be87487830698e23" - dependencies: - mime-db "~1.29.0" - mime@1.3.4, mime@1.3.x, mime@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" @@ -4992,13 +4842,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" - dependencies: - brace-expansion "^1.0.0" - -minimatch@^3.0.4, minimatch@~3.0.2: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -5043,7 +4887,7 @@ mocha@^3.1.2: mkdirp "0.5.1" supports-color "3.1.2" -moment@2.18.1, moment@2.x.x, moment@^2.10.3: +moment@2.18.1, moment@2.x.x, moment@^2.10.3, moment@^2.18.1: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" @@ -6429,7 +6273,7 @@ pym.js@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/pym.js/-/pym.js-1.2.0.tgz#feb1e2c9b396613e5172192b0cdd75408f9c8322" -q@1.5.0: +q@1.5.0, q@^1.1.2: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" @@ -6441,10 +6285,6 @@ q@2.0.3: pop-iterate "^1.0.1" weak-map "^1.0.5" -q@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/q/-/q-1.1.2.tgz#6357e291206701d99f197ab84e57e8ad196f2a89" - qs@6.4.0, qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" @@ -6796,10 +6636,6 @@ regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" -regenerator-runtime@^0.10.0: - version "0.10.4" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.4.tgz#74cb6598d3ba2eb18694e968a40e2b3b4df9cf93" - regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -7127,7 +6963,7 @@ shelljs@0.3.x: version "0.3.0" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" -shelljs@0.7.8: +shelljs@0.7.8, shelljs@^0.7.0: version "0.7.8" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" dependencies: @@ -7135,14 +6971,6 @@ shelljs@0.7.8: interpret "^1.0.0" rechoir "^0.6.2" -shelljs@^0.7.0: - version "0.7.7" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -7275,7 +7103,7 @@ source-map@0.4.x, source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: +source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -7648,10 +7476,6 @@ to-capital-case@^1.0.0: dependencies: to-space-case "^1.0.0" -to-fast-properties@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" - to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -7753,7 +7577,7 @@ type-detect@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea" -type-is@~1.6.14, type-is@~1.6.15: +type-is@~1.6.15: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" dependencies: @@ -8051,14 +7875,10 @@ word-wrap@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.1.0.tgz#356153d61d10610d600785c5d701288e0ae764a6" -word-wrap@1.2.3: +word-wrap@1.2.3, word-wrap@^1.0.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" -word-wrap@^1.0.3: - version "1.2.1" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.1.tgz#248f459b465d179a17bc407c854d3151d07e45d8" - wordwrap@0.0.2, wordwrap@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" From ffef2f640da5c4aa48944f586821bf42abc50b80 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 15:40:39 +0700 Subject: [PATCH 05/20] First implementation of ignore user plugin --- .eslintignore | 1 + .gitignore | 1 + .../src/components/AllCommentsPane.js | 2 - .../src/components/Comment.css | 13 +--- .../src/components/Comment.js | 16 ----- .../src/components/Stream.js | 7 --- .../src/components/TopRightMenu.js | 60 ------------------- .../src/containers/Stream.js | 3 +- .../coral-embed-stream/src/graphql/index.js | 12 ---- client/coral-framework/graphql/mutations.js | 2 +- plugin-api/beta/client/hocs/index.js | 1 + .../client/components/Menu.css | 4 ++ .../client/components/Menu.js | 13 ++-- .../client/containers/AuthorName.js | 4 ++ .../talk-plugin-ignore-user/client/.babelrc | 14 +++++ .../client/.eslintrc.json | 23 +++++++ .../client/components/IgnoreUserAction.css | 16 +++++ .../client/components/IgnoreUserAction.js | 9 +++ .../components/IgnoreUserConfirmation.css | 9 +++ .../components/IgnoreUserConfirmation.js | 14 +++++ .../client/containers/IgnoreUserAction.js | 34 +++++++++++ .../containers/IgnoreUserConfirmation.js | 44 ++++++++++++++ .../talk-plugin-ignore-user/client/index.js | 26 ++++++++ .../client/translations.yml | 5 ++ plugins/talk-plugin-ignore-user/index.js | 1 + 25 files changed, 217 insertions(+), 117 deletions(-) delete mode 100644 client/coral-embed-stream/src/components/TopRightMenu.js create mode 100644 plugins/talk-plugin-ignore-user/client/.babelrc create mode 100644 plugins/talk-plugin-ignore-user/client/.eslintrc.json create mode 100644 plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.css create mode 100644 plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.js create mode 100644 plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css create mode 100644 plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js create mode 100644 plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js create mode 100644 plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js create mode 100644 plugins/talk-plugin-ignore-user/client/index.js create mode 100644 plugins/talk-plugin-ignore-user/client/translations.yml create mode 100644 plugins/talk-plugin-ignore-user/index.js diff --git a/.eslintignore b/.eslintignore index 688e285c5..4805e34a4 100644 --- a/.eslintignore +++ b/.eslintignore @@ -21,5 +21,6 @@ plugins/* !plugins/talk-plugin-sort-most-respected !plugins/talk-plugin-author-menu !plugins/talk-plugin-member-since +!plugins/talk-plugin-ignore-user node_modules diff --git a/.gitignore b/.gitignore index f8be44f20..0a2ac00df 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,6 @@ plugins/* !plugins/talk-plugin-sort-most-respected !plugins/talk-plugin-author-menu !plugins/talk-plugin-member-since +!plugins/talk-plugin-ignore-user **/node_modules/* diff --git a/client/coral-embed-stream/src/components/AllCommentsPane.js b/client/coral-embed-stream/src/components/AllCommentsPane.js index 427d3a68b..1617b8c4f 100644 --- a/client/coral-embed-stream/src/components/AllCommentsPane.js +++ b/client/coral-embed-stream/src/components/AllCommentsPane.js @@ -126,7 +126,6 @@ class AllCommentsPane extends React.Component { root, comments, commentClassNames, - ignoreUser, setActiveReplyBox, activeReplyBox, notify, @@ -173,7 +172,6 @@ class AllCommentsPane extends React.Component { currentUser={currentUser} postFlag={postFlag} postDontAgree={postDontAgree} - ignoreUser={ignoreUser} commentIsIgnored={commentIsIgnored} loadMore={loadNewReplies} deleteAction={deleteAction} diff --git a/client/coral-embed-stream/src/components/Comment.css b/client/coral-embed-stream/src/components/Comment.css index 578df2d80..6dc8eee80 100644 --- a/client/coral-embed-stream/src/components/Comment.css +++ b/client/coral-embed-stream/src/components/Comment.css @@ -66,17 +66,6 @@ border-bottom: 1px solid rgba(255, 255, 255, 0.3); } -.topRight .popover { - margin-top: 1em; - right: 0px; -} - -.topRight .link.active, -.topRight .active .link { - padding-bottom: 0.125em; - border-bottom: 2px solid currentColor; -} - .editCommentForm { margin-bottom: 10px; } @@ -175,4 +164,4 @@ .username { margin-right: 5px; -} \ No newline at end of file +} diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index 205bc498b..87dc4e776 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -16,7 +16,6 @@ import mapValues from 'lodash/mapValues'; import LoadMore from './LoadMore'; import {getEditableUntilDate} from './util'; import {findCommentWithId} from '../graphql/utils'; -import {TopRightMenu} from './TopRightMenu'; import CommentContent from './CommentContent'; import Slot from 'coral-framework/components/Slot'; import IgnoredCommentTombstone from './IgnoredCommentTombstone'; @@ -187,9 +186,6 @@ export default class Comment extends React.Component { // given a comment, return whether it should be rendered as ignored commentIsIgnored: PropTypes.func, - // dispatch action to ignore another user - ignoreUser: PropTypes.func, - // edit a comment, passed (id, asset_id, { body }) editComment: PropTypes.func, @@ -317,7 +313,6 @@ export default class Comment extends React.Component { comment, postFlag, parentId, - ignoreUser, highlighted, postComment, currentUser, @@ -480,16 +475,6 @@ export default class Comment extends React.Component { } } - { isActive && (currentUser && (comment.user.id !== currentUser.id)) && - - /* TopRightMenu allows currentUser to ignore other users' comments */ - - - - } { !isActive && } @@ -600,7 +585,6 @@ export default class Comment extends React.Component { postFlag={postFlag} deleteAction={deleteAction} loadMore={loadMore} - ignoreUser={ignoreUser} charCountEnable={charCountEnable} maxCharCount={maxCharCount} showSignInDialog={showSignInDialog} diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index 4d46c8e87..575c1fd00 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -64,7 +64,6 @@ class Stream extends React.Component { postDontAgree, deleteAction, showSignInDialog, - ignoreUser, loadNewReplies, auth: {user}, emit, @@ -90,7 +89,6 @@ class Stream extends React.Component { data={data} root={root} commentClassNames={commentClassNames} - ignoreUser={ignoreUser} setActiveReplyBox={setActiveReplyBox} activeReplyBox={activeReplyBox} notify={notify} @@ -133,7 +131,6 @@ class Stream extends React.Component { postDontAgree, deleteAction, showSignInDialog, - ignoreUser, activeStreamTab, setActiveStreamTab, loadNewReplies, @@ -183,7 +180,6 @@ class Stream extends React.Component { root={root} comments={comments} commentClassNames={commentClassNames} - ignoreUser={ignoreUser} setActiveReplyBox={setActiveReplyBox} activeReplyBox={activeReplyBox} notify={notify} @@ -322,9 +318,6 @@ Stream.propTypes = { notify: PropTypes.func.isRequired, postComment: PropTypes.func.isRequired, - // dispatch action to ignore another user - ignoreUser: React.PropTypes.func, - // edit a comment, passed (id, asset_id, { body }) editComment: React.PropTypes.func }; diff --git a/client/coral-embed-stream/src/components/TopRightMenu.js b/client/coral-embed-stream/src/components/TopRightMenu.js deleted file mode 100644 index 47147e853..000000000 --- a/client/coral-embed-stream/src/components/TopRightMenu.js +++ /dev/null @@ -1,60 +0,0 @@ -import React, {PropTypes} from 'react'; -import {IgnoreUserWizard} from './IgnoreUserWizard'; -import Toggleable from './Toggleable'; - -// TopRightMenu appears as a dropdown in the top right of the comment. -// when you click the down cehvron, it expands and shows IgnoreUserWizard -// when you click 'cancel' in the wizard, it closes the menu -export class TopRightMenu extends React.Component { - static propTypes = { - - // comment on which this menu appears - comment: PropTypes.shape({ - user: PropTypes.shape({ - id: PropTypes.string.isRequired, - username: PropTypes.string.isRequired - }).isRequired - }).isRequired, - ignoreUser: PropTypes.func, - - // show notification to the user (e.g. for errors) - notify: PropTypes.func.isRequired, - } - constructor(props) { - super(props); - this.state = { - timesReset: 0 - }; - } - render() { - const {comment, ignoreUser, notify} = this.props; - - // timesReset is used as Toggleable key so it re-renders on reset (closing the toggleable) - const reset = () => this.setState({timesReset: this.state.timesReset + 1}); - const ignoreUserAndCloseMenuAndNotifyOnError = async ({id}) => { - - // close menu - reset(); - - // ignore user - try { - await ignoreUser({id}); - } catch (error) { - notify('error', 'Failed to ignore user'); - throw error; - } - }; - return ( - -
- -
-
- ); - } -} - diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index 194bfc5d9..d3279896c 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -5,7 +5,7 @@ import {bindActionCreators} from 'redux'; import {ADDTL_COMMENTS_ON_LOAD_MORE, THREADING_LEVEL} from '../constants/stream'; import { withPostComment, withPostFlag, withPostDontAgree, - withDeleteAction, withIgnoreUser, withEditComment + withDeleteAction, withEditComment } from 'coral-framework/graphql/mutations'; import * as authActions from 'coral-embed-stream/src/actions/auth'; @@ -374,7 +374,6 @@ export default compose( withPostComment, withPostFlag, withPostDontAgree, - withIgnoreUser, withDeleteAction, withEditComment, )(StreamContainer); diff --git a/client/coral-embed-stream/src/graphql/index.js b/client/coral-embed-stream/src/graphql/index.js index 9ec9a2132..d01e353fc 100644 --- a/client/coral-embed-stream/src/graphql/index.js +++ b/client/coral-embed-stream/src/graphql/index.js @@ -108,18 +108,6 @@ export default { `, }, mutations: { - IgnoreUser: ({variables}) => ({ - updateQueries: { - CoralEmbedStream_Embed: (previousData) => { - const ignoredUserId = variables.id; - const updated = update(previousData, {me: {ignoredUsers: {$push: [{ - id: ignoredUserId, - __typename: 'User', - }]}}}); - return updated; - } - } - }), StopIgnoringUser: ({variables}) => ({ updateQueries: { CoralEmbedStream_Profile: (previousData) => { diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index 91d2ae0ab..4254400bb 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -293,7 +293,7 @@ export const withIgnoreUser = withMutation( } `, { props: ({mutate}) => ({ - ignoreUser: ({id}) => { + ignoreUser: (id) => { return mutate({ variables: { id, diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index 1bc47868e..2659237f3 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -5,3 +5,4 @@ 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'; export {default as withEmit} from 'coral-framework/hocs/withEmit'; +export {withIgnoreUser} from 'coral-framework/graphql/mutations'; diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.css b/plugins/talk-plugin-author-menu/client/components/Menu.css index 86befe54a..e3a111235 100644 --- a/plugins/talk-plugin-author-menu/client/components/Menu.css +++ b/plugins/talk-plugin-author-menu/client/components/Menu.css @@ -35,3 +35,7 @@ transform: rotate(180deg); } +.actions { + display: flex; + justify-content: flex-end; +} diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.js b/plugins/talk-plugin-author-menu/client/components/Menu.js index fdedf6594..620bd59c9 100644 --- a/plugins/talk-plugin-author-menu/client/components/Menu.js +++ b/plugins/talk-plugin-author-menu/client/components/Menu.js @@ -5,11 +5,13 @@ import {Slot} from 'plugin-api/beta/client/components'; export default ({data, root, asset, comment, contentSlot}) => { if (contentSlot) { return ( - +
+ +
); } @@ -21,6 +23,7 @@ export default ({data, root, asset, comment, contentSlot}) => { queryData={{asset, root, comment}} /> ( + +); diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css new file mode 100644 index 000000000..5cd38f244 --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css @@ -0,0 +1,9 @@ +.root { + width: 250px; +} + +.actions { + display: flex; + justify-content: flex-end; +} + diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js new file mode 100644 index 000000000..ba2f62b0b --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js @@ -0,0 +1,14 @@ +import React from 'react'; +import styles from './IgnoreUserConfirmation.css'; +import {t} from 'plugin-api/beta/client/services'; + +export default ({ignoreUser}) => ( +
+ Do you really want to ignore this user? +
+ +
+
+); diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js new file mode 100644 index 000000000..422162a6e --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js @@ -0,0 +1,34 @@ +import React from 'react'; +import IgnoreUserAction from '../components/IgnoreUserAction'; +import {compose} from 'react-apollo'; +import {connect, withFragments} from 'plugin-api/beta/client/hocs'; +import {bindActionCreators} from 'redux'; +import {setContentSlot} from 'plugins/talk-plugin-author-menu/client/actions'; +import IgnoreUserConfirmation from './IgnoreUserConfirmation'; + +class IgnoreUserActionContainer extends React.Component { + + ignoreUser = () => { + this.props.setContentSlot('ignoreUserConfirmation'); + }; + + render() { + return ; + } +} + +const mapDispatchToProps = (dispatch) => + bindActionCreators({ + setContentSlot, + }, dispatch); + +const withIgnoreUserActionFragments = withFragments(IgnoreUserConfirmation.fragments); + +const enhance = compose( + connect(null, mapDispatchToProps), + withIgnoreUserActionFragments, +); + +export default enhance(IgnoreUserActionContainer); diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js new file mode 100644 index 000000000..5d014277c --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js @@ -0,0 +1,44 @@ +import React from 'react'; +import IgnoreUserConfirmation from '../components/IgnoreUserConfirmation'; +import {compose, gql} from 'react-apollo'; +import {connect, withFragments, withIgnoreUser} from 'plugin-api/beta/client/hocs'; +import {bindActionCreators} from 'redux'; +import {setContentSlot} from 'plugins/talk-plugin-author-menu/client/actions'; + +class IgnoreUserConfirmationContainer extends React.Component { + + ignoreUser = () => { + this.props.ignoreUser(this.props.comment.user.id); + this.props.setContentSlot(null); + }; + + render() { + return ; + } +} + +const mapDispatchToProps = (dispatch) => + bindActionCreators({ + setContentSlot, + }, dispatch); + +const withIgnoreUserConfirmationFragments = withFragments({ + comment: gql` + fragment TalkIgnoreUser_IgnoreUserConfirmation_comment on Comment { + user { + id + username + } + }`, +}); + +const enhance = compose( + connect(null, mapDispatchToProps), + withIgnoreUserConfirmationFragments, + withIgnoreUser, +); + +export default enhance(IgnoreUserConfirmationContainer); diff --git a/plugins/talk-plugin-ignore-user/client/index.js b/plugins/talk-plugin-ignore-user/client/index.js new file mode 100644 index 000000000..79f440126 --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/index.js @@ -0,0 +1,26 @@ +import IgnoreUserAction from './containers/IgnoreUserAction'; +import IgnoreUserConfirmation from './containers/IgnoreUserConfirmation'; +import translations from './translations.yml'; +import update from 'immutability-helper'; + +export default { + mutations: { + IgnoreUser: ({variables}) => ({ + updateQueries: { + CoralEmbedStream_Embed: (previousData) => { + const ignoredUserId = variables.id; + const updated = update(previousData, {me: {ignoredUsers: {$push: [{ + id: ignoredUserId, + __typename: 'User', + }]}}}); + return updated; + } + } + }), + }, + slots: { + authorMenuActions: [IgnoreUserAction], + ignoreUserConfirmation: [IgnoreUserConfirmation] + }, + translations +}; diff --git a/plugins/talk-plugin-ignore-user/client/translations.yml b/plugins/talk-plugin-ignore-user/client/translations.yml new file mode 100644 index 000000000..1e40c7ba1 --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/translations.yml @@ -0,0 +1,5 @@ +en: + talk-plugin-ignore-user: + ignore: "ignore" +es: + talk-plugin-ignore-user: diff --git a/plugins/talk-plugin-ignore-user/index.js b/plugins/talk-plugin-ignore-user/index.js new file mode 100644 index 000000000..f053ebf79 --- /dev/null +++ b/plugins/talk-plugin-ignore-user/index.js @@ -0,0 +1 @@ +module.exports = {}; From b2ef7fa795377cdb2f4cfb50a58a365a619b3f68 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 15:51:04 +0700 Subject: [PATCH 06/20] Fix tombstone bug --- .../src/components/AllCommentsPane.js | 11 +++----- .../src/components/Comment.js | 28 ++++++++++++------- .../src/components/Stream.js | 11 -------- .../src/containers/Comment.js | 5 ++++ 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/client/coral-embed-stream/src/components/AllCommentsPane.js b/client/coral-embed-stream/src/components/AllCommentsPane.js index 1617b8c4f..7602902df 100644 --- a/client/coral-embed-stream/src/components/AllCommentsPane.js +++ b/client/coral-embed-stream/src/components/AllCommentsPane.js @@ -1,7 +1,6 @@ import React from 'react'; import LoadMore from './LoadMore'; -import IgnoredCommentTombstone from './IgnoredCommentTombstone'; import NewCount from './NewCount'; import {TransitionGroup} from 'react-transition-group'; import {forEachError} from 'coral-framework/utils'; @@ -138,7 +137,6 @@ class AllCommentsPane extends React.Component { loadNewReplies, deleteAction, showSignInDialog, - commentIsIgnored, charCountEnable, maxCharCount, editComment, @@ -156,9 +154,8 @@ class AllCommentsPane extends React.Component { /> {view.map((comment) => { - return commentIsIgnored(comment) - ? - : ; + /> + ); })} u.id === comment.user.id) + ); + } + hasIgnoredReplies() { return this.props.comment.replies && - this.props.comment.replies.nodes.some((reply) => this.props.commentIsIgnored(reply)); + this.props.comment.replies.nodes.some((reply) => this.commentIsIgnored(reply)); } loadNewReplies = () => { @@ -327,12 +333,15 @@ export default class Comment extends React.Component { charCountEnable, showSignInDialog, liveUpdates, - commentIsIgnored, animateEnter, emit, commentClassNames = [] } = this.props; + if (this.commentIsIgnored(comment)) { + return ; + } + const view = this.getVisibileReplies(); // Inactive comments can be viewed by moderators and admins (e.g. using permalinks). @@ -566,9 +575,8 @@ export default class Comment extends React.Component { {view.map((reply) => { - return commentIsIgnored(reply) - ? - : ; + /> + ); })}
diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index 575c1fd00..89e7b13ae 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -40,15 +40,6 @@ class Stream extends React.Component { } } - commentIsIgnored = (comment) => { - const me = this.props.root.me; - return ( - me && - me.ignoredUsers && - me.ignoredUsers.find((u) => u.id === comment.user.id) - ); - }; - renderHighlightedComment() { const { data, @@ -104,7 +95,6 @@ class Stream extends React.Component { deleteAction={deleteAction} showSignInDialog={showSignInDialog} key={topLevelComment.id} - commentIsIgnored={this.commentIsIgnored} comment={topLevelComment} charCountEnable={asset.settings.charCountEnable} maxCharCount={asset.settings.charCount} @@ -193,7 +183,6 @@ class Stream extends React.Component { loadNewReplies={loadNewReplies} deleteAction={deleteAction} showSignInDialog={showSignInDialog} - commentIsIgnored={this.commentIsIgnored} charCountEnable={asset.settings.charCountEnable} maxCharCount={asset.settings.charCount} editComment={editComment} diff --git a/client/coral-embed-stream/src/containers/Comment.js b/client/coral-embed-stream/src/containers/Comment.js index a4bfbc0eb..f24dc8b01 100644 --- a/client/coral-embed-stream/src/containers/Comment.js +++ b/client/coral-embed-stream/src/containers/Comment.js @@ -93,6 +93,11 @@ const withCommentFragments = withFragments({ fragment CoralEmbedStream_Comment_root on RootQuery { __typename ${getSlotFragmentSpreads(slots, 'root')} + me { + ignoredUsers { + id + } + } } `, asset: gql` From 98cb34f55456b191c32d374f65166391e2f15182 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 16:25:19 +0700 Subject: [PATCH 07/20] Don't ignore myself --- .../client/containers/IgnoreUserAction.js | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js index 422162a6e..7fc32d0e8 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js @@ -1,10 +1,11 @@ import React from 'react'; import IgnoreUserAction from '../components/IgnoreUserAction'; -import {compose} from 'react-apollo'; -import {connect, withFragments} from 'plugin-api/beta/client/hocs'; +import {compose, gql} from 'react-apollo'; +import {connect, withFragments, excludeIf} from 'plugin-api/beta/client/hocs'; import {bindActionCreators} from 'redux'; import {setContentSlot} from 'plugins/talk-plugin-author-menu/client/actions'; import IgnoreUserConfirmation from './IgnoreUserConfirmation'; +import {getDefinitionName} from 'plugin-api/beta/client/utils'; class IgnoreUserActionContainer extends React.Component { @@ -24,11 +25,29 @@ const mapDispatchToProps = (dispatch) => setContentSlot, }, dispatch); -const withIgnoreUserActionFragments = withFragments(IgnoreUserConfirmation.fragments); +const withIgnoreUserActionFragments = withFragments({ + root: gql` + fragment TalkIgnoreUser_IgnoreUserAction_root on RootQuery { + me { + id + } + } + `, + comment: gql` + fragment TalkIgnoreUser_IgnoreUserAction_comment on Comment { + user { + id + } + ...${getDefinitionName(IgnoreUserConfirmation.fragments.comment)} + } + ${IgnoreUserConfirmation.fragments.comment} + `, +}); const enhance = compose( connect(null, mapDispatchToProps), withIgnoreUserActionFragments, + excludeIf(({root: {me}, comment}) => me.id === comment.user.id), ); export default enhance(IgnoreUserActionContainer); From c0252e160bb4c05754a6863f567d2e875c567679 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 16:44:53 +0700 Subject: [PATCH 08/20] Fix reply fragments --- client/coral-embed-stream/src/containers/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/containers/Comment.js b/client/coral-embed-stream/src/containers/Comment.js index f24dc8b01..11a668371 100644 --- a/client/coral-embed-stream/src/containers/Comment.js +++ b/client/coral-embed-stream/src/containers/Comment.js @@ -85,6 +85,7 @@ const singleCommentFragment = gql` edited editableUntil } + ${getSlotFragmentSpreads(slots, 'comment')} } `; @@ -121,7 +122,6 @@ const withCommentFragments = withFragments({ endCursor } `, THREADING_LEVEL)} - ${getSlotFragmentSpreads(slots, 'comment')} } ${singleCommentFragment} ` From 89258638d4a8a7a7bec75ea66f188ad51fcbcda8 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 22:35:05 +0700 Subject: [PATCH 09/20] Correct exclude if logic --- .../client/containers/IgnoreUserAction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js index 7fc32d0e8..d7e9d38b5 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserAction.js @@ -47,7 +47,7 @@ const withIgnoreUserActionFragments = withFragments({ const enhance = compose( connect(null, mapDispatchToProps), withIgnoreUserActionFragments, - excludeIf(({root: {me}, comment}) => me.id === comment.user.id), + excludeIf(({root: {me}, comment}) => !me || me.id === comment.user.id), ); export default enhance(IgnoreUserActionContainer); From 74e8c28f45cfba45002f04766366fba94f0977ad Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 23:13:00 +0700 Subject: [PATCH 10/20] Apply styling --- .../client/components/Menu.css | 6 +++- .../client/components/IgnoreUserAction.css | 21 ++++++------ .../client/components/IgnoreUserAction.js | 2 +- .../components/IgnoreUserConfirmation.css | 32 ++++++++++++++++++- .../components/IgnoreUserConfirmation.js | 11 +++++-- .../containers/IgnoreUserConfirmation.js | 5 +++ .../client/translations.yml | 6 +++- .../client/components/MemberSinceInfo.css | 9 ++++-- 8 files changed, 72 insertions(+), 20 deletions(-) diff --git a/plugins/talk-plugin-author-menu/client/components/Menu.css b/plugins/talk-plugin-author-menu/client/components/Menu.css index e3a111235..dd149ce18 100644 --- a/plugins/talk-plugin-author-menu/client/components/Menu.css +++ b/plugins/talk-plugin-author-menu/client/components/Menu.css @@ -12,7 +12,6 @@ left: 0px; min-width: 20px; text-align: left; - color: #616161; } .menu::before{ @@ -38,4 +37,9 @@ .actions { display: flex; justify-content: flex-end; + margin-top: 8px; + + &:empty { + display: none; + } } diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.css b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.css index cefd32d40..ac818278c 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.css +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.css @@ -2,15 +2,16 @@ white-space: nowrap; } -.memberSince { - color: #484747; - margin-left: 4px; - letter-spacing: 0.2px; - font-size: 0.9em; - vertical-align: middle; -} +.button { + composes: buttonReset from "coral-framework/styles/reset.css"; + border: 1px solid rgba(1, 1, 1, 0.8); + border-radius: 1px; + padding: 3px 6px; + font-size: 12px; + transition: color 100ms, background 100ms; -.icon { - font-size: 1.4em; - vertical-align: middle; + &:hover { + background-color: rgba(1, 1, 1, 0.8); + color: white; + } } diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.js b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.js index 00817f38b..0649999ca 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.js +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserAction.js @@ -4,6 +4,6 @@ import {t} from 'plugin-api/beta/client/services'; export default ({ignoreUser}) => ( ); diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css index 5cd38f244..0439da88c 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css @@ -1,9 +1,39 @@ .root { - width: 250px; + width: 200px; } .actions { display: flex; justify-content: flex-end; + margin-top: 8px; } +.message { + font-size: 13px; +} + +.button { + composes: buttonReset from "coral-framework/styles/reset.css"; + border: 1px solid rgba(1, 1, 1, 0.8); + border-radius: 1px; + padding: 3px 6px; + font-size: 12px; + transition: color 100ms, background 100ms; + + &:hover { + background-color: rgba(1, 1, 1, 0.8); + color: white; + } +} + +.cancel { + composes: buttonReset from "coral-framework/styles/reset.css"; + padding: 3px 6px; + font-size: 12px; + transition: color 100ms; + margin-right: 4px; + + &:hover { + color: rgba(1, 1, 1, 0.75); + } +} diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js index ba2f62b0b..10a4aac5f 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js @@ -2,12 +2,17 @@ import React from 'react'; import styles from './IgnoreUserConfirmation.css'; import {t} from 'plugin-api/beta/client/services'; -export default ({ignoreUser}) => ( +export default ({ignoreUser, cancel}) => (
- Do you really want to ignore this user? +
+ {t('talk-plugin-ignore-user.confirmation')} +
+
diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js index 5d014277c..a97ebe228 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js @@ -12,10 +12,15 @@ class IgnoreUserConfirmationContainer extends React.Component { this.props.setContentSlot(null); }; + cancel = () => { + this.props.setContentSlot(null); + } + render() { return ; } } diff --git a/plugins/talk-plugin-ignore-user/client/translations.yml b/plugins/talk-plugin-ignore-user/client/translations.yml index 1e40c7ba1..d3d3c2aba 100644 --- a/plugins/talk-plugin-ignore-user/client/translations.yml +++ b/plugins/talk-plugin-ignore-user/client/translations.yml @@ -1,5 +1,9 @@ en: talk-plugin-ignore-user: - ignore: "ignore" + ignore_user: Ignore User + cancel: Cancel + confirmation: | + When you ignore a user, all comments they wrote on the site will be hidden from you. You can + undo this later from My Profile. es: talk-plugin-ignore-user: diff --git a/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css b/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css index cefd32d40..3cf2fb75d 100644 --- a/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css +++ b/plugins/talk-plugin-member-since/client/components/MemberSinceInfo.css @@ -2,15 +2,18 @@ white-space: nowrap; } +.root:not(:last-child) { + margin-bottom: 4px; +} + .memberSince { - color: #484747; margin-left: 4px; letter-spacing: 0.2px; - font-size: 0.9em; + font-size: 13px; vertical-align: middle; } .icon { - font-size: 1.4em; + font-size: 18px; vertical-align: middle; } From f8297e96524f68893c9b727f2a621d321f7dc6a4 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 23:29:36 +0700 Subject: [PATCH 11/20] Hide menu after action --- .../talk-plugin-author-menu/client/actions.js | 11 ++++++- .../client/constants.js | 2 ++ .../client/containers/AuthorName.js | 33 ++++++++++--------- .../talk-plugin-author-menu/client/reducer.js | 14 +++++++- .../containers/IgnoreUserConfirmation.js | 8 ++--- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/plugins/talk-plugin-author-menu/client/actions.js b/plugins/talk-plugin-author-menu/client/actions.js index 0a806749d..960e66bb4 100644 --- a/plugins/talk-plugin-author-menu/client/actions.js +++ b/plugins/talk-plugin-author-menu/client/actions.js @@ -1,4 +1,4 @@ -import {SET_CONTENT_SLOT, RESET_CONTENT_SLOT} from './constants'; +import {SET_CONTENT_SLOT, RESET_CONTENT_SLOT, OPEN_MENU, CLOSE_MENU} from './constants'; export const setContentSlot = (slot) => ({ type: SET_CONTENT_SLOT, @@ -8,3 +8,12 @@ export const setContentSlot = (slot) => ({ export const resetContentSlot = () => ({ type: RESET_CONTENT_SLOT, }); + +export const openMenu = (id) => ({ + type: OPEN_MENU, + id, +}); + +export const closeMenu = () => ({ + type: CLOSE_MENU, +}); diff --git a/plugins/talk-plugin-author-menu/client/constants.js b/plugins/talk-plugin-author-menu/client/constants.js index a11de608a..1d14e94d4 100644 --- a/plugins/talk-plugin-author-menu/client/constants.js +++ b/plugins/talk-plugin-author-menu/client/constants.js @@ -2,4 +2,6 @@ const prefix = 'TALK_AUTHOR_MENU'; export const SET_CONTENT_SLOT = `${prefix}_SET_CONTENT_SLOT`; export const RESET_CONTENT_SLOT = `${prefix}_RESET_CONTENT_SLOT`; +export const OPEN_MENU = `${prefix}_OPEN_MENU`; +export const CLOSE_MENU = `${prefix}_CLOSE_MENU`; diff --git a/plugins/talk-plugin-author-menu/client/containers/AuthorName.js b/plugins/talk-plugin-author-menu/client/containers/AuthorName.js index cbb8c84ee..9d9188167 100644 --- a/plugins/talk-plugin-author-menu/client/containers/AuthorName.js +++ b/plugins/talk-plugin-author-menu/client/containers/AuthorName.js @@ -2,29 +2,23 @@ import React from 'react'; import {connect, withFragments} from 'plugin-api/beta/client/hocs'; import {bindActionCreators} from 'redux'; import AuthorName from '../components/AuthorName'; -import {setContentSlot, resetContentSlot} from '../actions'; +import {setContentSlot, resetContentSlot, openMenu, closeMenu} from '../actions'; import {compose, gql} from 'react-apollo'; import {getSlotFragmentSpreads} from 'plugin-api/beta/client/utils'; class AuthorNameContainer extends React.Component { - state = { - menuVisible: false - }; toggleMenu = () => { - this.setState({ - menuVisible: !this.state.menuVisible, - }); + if (this.props.showMenuForComment === this.props.comment.id) { + this.props.closeMenu(); + } else { + this.props.openMenu(this.props.comment.id); + } } hideMenu = () => { - if (this.state.menuVisible) { - this.setState({ - menuVisible: false - }); - if (this.props.contentSlot) { - this.props.resetContentSlot(); - } + if (this.props.showMenuForComment === this.props.comment.id) { + this.props.closeMenu(); } } @@ -35,7 +29,7 @@ class AuthorNameContainer extends React.Component { asset={this.props.asset} comment={this.props.comment} contentSlot={this.props.contentSlot} - menuVisible={this.state.menuVisible} + menuVisible={this.props.showMenuForComment === this.props.comment.id} toggleMenu={this.toggleMenu} hideMenu={this.hideMenu} />; @@ -49,10 +43,16 @@ const slots = [ const mapStateToProps = ({talkPluginAuthorMenu: state}) => ({ contentSlot: state.contentSlot, + showMenuForComment: state.showMenuForComment, }); const mapDispatchToProps = (dispatch) => - bindActionCreators({setContentSlot, resetContentSlot}, dispatch); + bindActionCreators({ + setContentSlot, + resetContentSlot, + openMenu, + closeMenu, + }, dispatch); const withAuthorNameFragments = withFragments({ root: gql` @@ -68,6 +68,7 @@ const withAuthorNameFragments = withFragments({ comment: gql` fragment TalkAuthorMenu_AuthorName_comment on Comment { __typename + id user { username } diff --git a/plugins/talk-plugin-author-menu/client/reducer.js b/plugins/talk-plugin-author-menu/client/reducer.js index 4f04d07ed..822c2a6a8 100644 --- a/plugins/talk-plugin-author-menu/client/reducer.js +++ b/plugins/talk-plugin-author-menu/client/reducer.js @@ -1,7 +1,8 @@ -import {SET_CONTENT_SLOT, RESET_CONTENT_SLOT} from './constants'; +import {SET_CONTENT_SLOT, RESET_CONTENT_SLOT, OPEN_MENU, CLOSE_MENU} from './constants'; const initialState = { contentSlot: null, + showMenuForComment: null, }; export default function reducer(state = initialState, action) { @@ -16,6 +17,17 @@ export default function reducer(state = initialState, action) { ...state, contentSlot: initialState.contentSlot, }; + case OPEN_MENU: + return { + ...state, + showMenuForComment: action.id, + }; + case CLOSE_MENU: + return { + ...state, + showMenuForComment: null, + contentSlot: null, + }; default : return state; } diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js index a97ebe228..4821fae9b 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js @@ -3,17 +3,17 @@ import IgnoreUserConfirmation from '../components/IgnoreUserConfirmation'; import {compose, gql} from 'react-apollo'; import {connect, withFragments, withIgnoreUser} from 'plugin-api/beta/client/hocs'; import {bindActionCreators} from 'redux'; -import {setContentSlot} from 'plugins/talk-plugin-author-menu/client/actions'; +import {closeMenu} from 'plugins/talk-plugin-author-menu/client/actions'; class IgnoreUserConfirmationContainer extends React.Component { ignoreUser = () => { this.props.ignoreUser(this.props.comment.user.id); - this.props.setContentSlot(null); + this.props.closeMenu(); }; cancel = () => { - this.props.setContentSlot(null); + this.props.closeMenu(); } render() { @@ -27,7 +27,7 @@ class IgnoreUserConfirmationContainer extends React.Component { const mapDispatchToProps = (dispatch) => bindActionCreators({ - setContentSlot, + closeMenu, }, dispatch); const withIgnoreUserConfirmationFragments = withFragments({ From 2d4adb60be38bab47a50c93f385645dd3e8e6a27 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Mon, 4 Sep 2017 23:55:44 +0700 Subject: [PATCH 12/20] Show notification on success --- client/coral-embed/src/Snackbar.js | 2 +- client/coral-framework/services/notification.js | 12 ++++++------ plugin-api/beta/client/actions/notification.js | 2 +- .../client/containers/IgnoreUserConfirmation.js | 4 ++++ .../talk-plugin-ignore-user/client/translations.yml | 2 ++ 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/client/coral-embed/src/Snackbar.js b/client/coral-embed/src/Snackbar.js index c518288c6..11219102d 100644 --- a/client/coral-embed/src/Snackbar.js +++ b/client/coral-embed/src/Snackbar.js @@ -38,7 +38,7 @@ export default class Snackbar { } alert(message) { - const [type, text] = message.split('|'); + const {type, text} = JSON.parse(message); this.el.style.transform = 'translate(-50%, 20px)'; this.el.style.opacity = 0; this.el.className = `coral-notif-${type}`; diff --git a/client/coral-framework/services/notification.js b/client/coral-framework/services/notification.js index 5730200ad..a3f1a6520 100644 --- a/client/coral-framework/services/notification.js +++ b/client/coral-framework/services/notification.js @@ -5,14 +5,14 @@ */ export function createNotificationService(pym) { return { - success(msg) { - pym.sendMessage('coral-alert', `success|${msg}`); + success(text) { + pym.sendMessage('coral-alert', JSON.stringify({kind: 'success', text})); }, - error(msg) { - pym.sendMessage('coral-alert', `error|${msg}`); + error(text) { + pym.sendMessage('coral-alert', JSON.stringify({kind: 'error', text})); }, - info(msg) { - pym.sendMessage('coral-alert', `info|${msg}`); + info(text) { + pym.sendMessage('coral-alert', JSON.stringify({kind: 'info', text})); }, }; } diff --git a/plugin-api/beta/client/actions/notification.js b/plugin-api/beta/client/actions/notification.js index c1a75cb7a..0fae2b983 100644 --- a/plugin-api/beta/client/actions/notification.js +++ b/plugin-api/beta/client/actions/notification.js @@ -1 +1 @@ -export {addNotification} from 'coral-framework/actions/notification'; +export {notify} from 'coral-framework/actions/notification'; diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js index 4821fae9b..2e1c7a820 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js @@ -4,11 +4,14 @@ import {compose, gql} from 'react-apollo'; import {connect, withFragments, withIgnoreUser} from 'plugin-api/beta/client/hocs'; import {bindActionCreators} from 'redux'; import {closeMenu} from 'plugins/talk-plugin-author-menu/client/actions'; +import {notify} from 'plugin-api/beta/client/actions/notification'; +import {t} from 'plugin-api/beta/client/services'; class IgnoreUserConfirmationContainer extends React.Component { ignoreUser = () => { this.props.ignoreUser(this.props.comment.user.id); + this.props.notify('success', t('talk-plugin-ignore-user.notify_success', this.props.comment.user.username)); this.props.closeMenu(); }; @@ -28,6 +31,7 @@ class IgnoreUserConfirmationContainer extends React.Component { const mapDispatchToProps = (dispatch) => bindActionCreators({ closeMenu, + notify, }, dispatch); const withIgnoreUserConfirmationFragments = withFragments({ diff --git a/plugins/talk-plugin-ignore-user/client/translations.yml b/plugins/talk-plugin-ignore-user/client/translations.yml index d3d3c2aba..a10c68a8d 100644 --- a/plugins/talk-plugin-ignore-user/client/translations.yml +++ b/plugins/talk-plugin-ignore-user/client/translations.yml @@ -5,5 +5,7 @@ en: confirmation: | When you ignore a user, all comments they wrote on the site will be hidden from you. You can undo this later from My Profile. + notify_success: | + You are now ignoring {0}. You can undo this action from My Profile. es: talk-plugin-ignore-user: From 123935c8bcdf16608c2b85e41e37691d05c0a0ba Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 00:00:27 +0700 Subject: [PATCH 13/20] Also notify on errors --- .../client/containers/IgnoreUserConfirmation.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js index 2e1c7a820..68492414e 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js @@ -6,13 +6,20 @@ import {bindActionCreators} from 'redux'; import {closeMenu} from 'plugins/talk-plugin-author-menu/client/actions'; import {notify} from 'plugin-api/beta/client/actions/notification'; import {t} from 'plugin-api/beta/client/services'; +import {getErrorMessages} from 'plugin-api/beta/client/utils'; class IgnoreUserConfirmationContainer extends React.Component { ignoreUser = () => { - this.props.ignoreUser(this.props.comment.user.id); - this.props.notify('success', t('talk-plugin-ignore-user.notify_success', this.props.comment.user.username)); - this.props.closeMenu(); + const {ignoreUser, notify, comment, closeMenu} = this.props; + ignoreUser(comment.user.id) + .then(() => { + notify('success', t('talk-plugin-ignore-user.notify_success', comment.user.username)); + }) + .catch((err) => { + notify('error', getErrorMessages(err)); + }); + closeMenu(); }; cancel = () => { From 07f5f42870aab517d8d6d387e5a894a972fadd85 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 00:16:27 +0700 Subject: [PATCH 14/20] Optimized render --- plugin-api/beta/client/utils/index.js | 1 + .../client/containers/AuthorName.js | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/plugin-api/beta/client/utils/index.js b/plugin-api/beta/client/utils/index.js index 6dd18f3a1..3fe742569 100644 --- a/plugin-api/beta/client/utils/index.js +++ b/plugin-api/beta/client/utils/index.js @@ -7,4 +7,5 @@ export { capitalize, getErrorMessages, getDefinitionName, + getShallowChanges, } from 'coral-framework/utils'; diff --git a/plugins/talk-plugin-author-menu/client/containers/AuthorName.js b/plugins/talk-plugin-author-menu/client/containers/AuthorName.js index 9d9188167..78663b603 100644 --- a/plugins/talk-plugin-author-menu/client/containers/AuthorName.js +++ b/plugins/talk-plugin-author-menu/client/containers/AuthorName.js @@ -4,10 +4,28 @@ import {bindActionCreators} from 'redux'; import AuthorName from '../components/AuthorName'; import {setContentSlot, resetContentSlot, openMenu, closeMenu} from '../actions'; import {compose, gql} from 'react-apollo'; -import {getSlotFragmentSpreads} from 'plugin-api/beta/client/utils'; +import {getSlotFragmentSpreads, getShallowChanges} from 'plugin-api/beta/client/utils'; class AuthorNameContainer extends React.Component { + shouldComponentUpdate(nextProps) { + + // Specifically handle `showMenuForComment` if it is the only change. + const changes = getShallowChanges(this.props, nextProps); + if (changes.length === 1 && changes[0] === 'showMenuForComment') { + const commentId = this.props.comment.id; + if ( + commentId !== this.props.showMenuForComment && + commentId !== nextProps.showMenuForComment + ) { + return false; + } + } + + // Prevent Slot from rerendering when no props has shallowly changed. + return changes.length !== 0; + } + toggleMenu = () => { if (this.props.showMenuForComment === this.props.comment.id) { this.props.closeMenu(); From 44e3d0b811702a02c9e45e215b4495a4c521bb3d Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 00:28:07 +0700 Subject: [PATCH 15/20] Add title --- .../client/components/IgnoreUserConfirmation.css | 6 ++++++ .../client/components/IgnoreUserConfirmation.js | 9 ++++++--- .../client/containers/IgnoreUserConfirmation.js | 2 +- plugins/talk-plugin-ignore-user/client/translations.yml | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css index 0439da88c..4f3d8e9da 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.css @@ -12,6 +12,12 @@ font-size: 13px; } +.title { + padding: 0; + margin: 0 0 8px 0; + font-size: 15px; +} + .button { composes: buttonReset from "coral-framework/styles/reset.css"; border: 1px solid rgba(1, 1, 1, 0.8); diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js index 10a4aac5f..9265dfda2 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js @@ -2,9 +2,12 @@ import React from 'react'; import styles from './IgnoreUserConfirmation.css'; import {t} from 'plugin-api/beta/client/services'; -export default ({ignoreUser, cancel}) => ( -
+export default ({ignoreUser, cancel, username}) => ( +
+ ); diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js index 68492414e..fdf6d1986 100644 --- a/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoreUserConfirmation.js @@ -28,7 +28,7 @@ class IgnoreUserConfirmationContainer extends React.Component { render() { return ; diff --git a/plugins/talk-plugin-ignore-user/client/translations.yml b/plugins/talk-plugin-ignore-user/client/translations.yml index a10c68a8d..0eb07d101 100644 --- a/plugins/talk-plugin-ignore-user/client/translations.yml +++ b/plugins/talk-plugin-ignore-user/client/translations.yml @@ -7,5 +7,6 @@ en: undo this later from My Profile. notify_success: | You are now ignoring {0}. You can undo this action from My Profile. + confirmation_title: Ignore {0}? es: talk-plugin-ignore-user: From e1a5a64b3995012506707ecc17837d348e82b37d Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 01:09:43 +0700 Subject: [PATCH 16/20] Pluginize stop ignoring user feature in profile --- .../coral-embed-stream/src/graphql/index.js | 15 ------- .../components/IgnoredUsers.css | 24 ----------- .../coral-settings/components/IgnoredUsers.js | 43 ------------------- .../containers/ProfileContainer.js | 29 +++++-------- locales/en.yml | 3 -- locales/es.yml | 2 - locales/fr.yml | 1 - locales/pt_BR.yml | 3 -- plugin-api/beta/client/hocs/index.js | 5 ++- .../client/components/IgnoredUserSection.css | 22 ++++++++++ .../client/components/IgnoredUserSection.js | 23 ++++++++++ .../client/containers/IgnoredUserSection.js | 36 ++++++++++++++++ .../talk-plugin-ignore-user/client/index.js | 19 +++++++- .../client/translations.yml | 13 ++++++ 14 files changed, 126 insertions(+), 112 deletions(-) delete mode 100644 client/coral-settings/components/IgnoredUsers.css delete mode 100644 client/coral-settings/components/IgnoredUsers.js create mode 100644 plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.css create mode 100644 plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.js create mode 100644 plugins/talk-plugin-ignore-user/client/containers/IgnoredUserSection.js diff --git a/client/coral-embed-stream/src/graphql/index.js b/client/coral-embed-stream/src/graphql/index.js index d01e353fc..09470de14 100644 --- a/client/coral-embed-stream/src/graphql/index.js +++ b/client/coral-embed-stream/src/graphql/index.js @@ -108,21 +108,6 @@ export default { `, }, mutations: { - StopIgnoringUser: ({variables}) => ({ - updateQueries: { - CoralEmbedStream_Profile: (previousData) => { - const noLongerIgnoredUserId = variables.id; - - // remove noLongerIgnoredUserId from ignoredUsers - const updated = update(previousData, {me: {ignoredUsers: { - $apply: (ignoredUsers) => { - return ignoredUsers.filter((u) => u.id !== noLongerIgnoredUserId); - } - }}}); - return updated; - } - } - }), PostComment: ({ variables: {comment: {asset_id, body, parent_id, tags = []}}, state: {auth}, diff --git a/client/coral-settings/components/IgnoredUsers.css b/client/coral-settings/components/IgnoredUsers.css deleted file mode 100644 index 716140256..000000000 --- a/client/coral-settings/components/IgnoredUsers.css +++ /dev/null @@ -1,24 +0,0 @@ -.ignoredUser { - display: table-row; -} - -.ignoredUserList { - display: table; -} - -.ignoredUser > * { - display: table-cell; -} - -.stopListening { - color: #D0011B; -} - -.link { - text-decoration: underline; - cursor: pointer; -} - -.stopListening:before { - content: '\00a0\00a0\00a0\00a0'; -} \ No newline at end of file diff --git a/client/coral-settings/components/IgnoredUsers.js b/client/coral-settings/components/IgnoredUsers.js deleted file mode 100644 index a8723161f..000000000 --- a/client/coral-settings/components/IgnoredUsers.js +++ /dev/null @@ -1,43 +0,0 @@ -import React, {Component, PropTypes} from 'react'; -import t from 'coral-framework/services/i18n'; -import styles from './IgnoredUsers.css'; - -class IgnoredUsers extends Component { - static propTypes = { - users: PropTypes.arrayOf(PropTypes.shape({ - username: PropTypes.string, - id: PropTypes.string, - })).isRequired, - - // accepts { id } - stopIgnoring: PropTypes.func.isRequired, - } - render() { - const {users, stopIgnoring} = this.props; - return ( -
- { - users.length - ?

{t('framework.because_you_ignored')}

- : null - } -
- { - users.map(({username, id}) => ( - -
{ username }
-
- stopIgnoring({id})} - className={styles.link}>{t('framework.stop_ignoring')} -
-
- )) - } -
-
- ); - } -} - -export default IgnoredUsers; diff --git a/client/coral-settings/containers/ProfileContainer.js b/client/coral-settings/containers/ProfileContainer.js index db47de8e2..aab0e2a6a 100644 --- a/client/coral-settings/containers/ProfileContainer.js +++ b/client/coral-settings/containers/ProfileContainer.js @@ -3,12 +3,10 @@ import {compose, gql} from 'react-apollo'; import React, {Component} from 'react'; import {bindActionCreators} from 'redux'; import {withQuery} from 'coral-framework/hocs'; - -import {withStopIgnoringUser} from 'coral-framework/graphql/mutations'; +import Slot from 'coral-framework/components/Slot'; import {link} from 'coral-framework/services/pym'; import NotLoggedIn from '../components/NotLoggedIn'; -import IgnoredUsers from '../components/IgnoredUsers'; import {Spinner} from 'coral-ui'; import CommentHistory from 'talk-plugin-history/CommentHistory'; @@ -55,7 +53,7 @@ class ProfileContainer extends Component { }; render() { - const {auth, auth: {user}, showSignInDialog, stopIgnoringUser, root, data} = this.props; + const {auth, auth: {user}, showSignInDialog, root, data} = this.props; const {me} = this.props.root; const loading = this.props.data.loading; @@ -77,15 +75,11 @@ class ProfileContainer extends Component {

{user.username}

{emailAddress ?

{emailAddress}

: null} - {me.ignoredUsers && me.ignoredUsers.length - ?
-

{t('framework.ignored_users')}

- -
- : null} +
@@ -98,8 +92,10 @@ class ProfileContainer extends Component { } } -// TODO: This Slot should be included in `talk-plugin-history` instead. const slots = [ + 'profileSections', + + // TODO: This Slot should be included in `talk-plugin-history` instead. 'commentContent', ]; @@ -143,10 +139,6 @@ const withProfileQuery = withQuery( query CoralEmbedStream_Profile { me { id - ignoredUsers { - id, - username, - } comments(query: {limit: 10}) { ...TalkSettings_CommentConnectionFragment } @@ -165,6 +157,5 @@ const mapDispatchToProps = (dispatch) => export default compose( connect(mapStateToProps, mapDispatchToProps), - withStopIgnoringUser, withProfileQuery )(ProfileContainer); diff --git a/locales/en.yml b/locales/en.yml index 791bc1121..4d215fd06 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -219,7 +219,6 @@ en: framework: banned_account_header: "Your account is currently banned." banned_account_body: "This means that you cannot Like, Report, or write comments." - because_you_ignored: "Because you ignored the following commenters, their comments are hidden." comment: comment comment_is_ignored: "This comment is hidden because you ignored this user." comments: comments @@ -230,13 +229,11 @@ en: error: "Usernames can contain letters numbers and _ only" label: "New Username" msg: "Your account is currently suspended because your username has been deemed inappropriate. To restore your account please enter a new username. Please contact us if you have any questions." - ignored_users: "Ignored users" my_comments: "My Comments" my_profile: "My profile" new_count: "View {0} new {1}" profile: Profile show_all_comments: "Show all comments" - stop_ignoring: "Stop ignoring" success_bio_update: "Your biography has been updated" success_name_update: "Your username has been updated" success_update_settings: "The changes you have made have been applied to the comment stream on this article" diff --git a/locales/es.yml b/locales/es.yml index 99f55d32b..f9b675a10 100644 --- a/locales/es.yml +++ b/locales/es.yml @@ -227,13 +227,11 @@ es: error: "Nombres de usuarios pueden solamente incluir letras, números y _" label: "Nuevo Nombre" msg: "Tu cuenta está suspendida porque tu nombre de usuario ha sido considerado no apropiado para el espacio. Para recuperar la cuenta, por favor ingresar un nuevo nombre de usuario. Contáctanos si tienes alguna pregunta." - ignored_users: "Usuarios ignorados" my_comments: "Mis Comentarios" my_profile: "Mi perfil" new_count: "Ver {0} {1} nuevo" profile: Perfil show_all_comments: "Mostrar todos los comentarios" - stop_ignoring: "No ignorar más" success_bio_update: "Tu biografia fue actualizada" success_name_update: "Tu nombre de usuario ha sido actualizado" success_update_settings: "La configuración de este articulo fue actualizada" diff --git a/locales/fr.yml b/locales/fr.yml index 77231e17b..5ece19c67 100644 --- a/locales/fr.yml +++ b/locales/fr.yml @@ -188,7 +188,6 @@ fr: error: "Les noms d'utilisateur ne peuvent contenir que des chiffres, des lettres et \"_\"" label: "Nouveau nom d'utilisateur" msg: "Votre compte est actuellement suspendu car votre nom d'utilisateur a été jugé inapproprié. Pour restaurer votre compte, entrez un nouveau nom d'utilisateur. Contactez-nous si vous avez des questions." - ignored_users: "Utilisateurs ignorés" my_comments: "Mes commentaires" my_profile: "Mon profil" new_count: "Voir {0} nouveau {1}" diff --git a/locales/pt_BR.yml b/locales/pt_BR.yml index 0e606fd81..e2e93c531 100644 --- a/locales/pt_BR.yml +++ b/locales/pt_BR.yml @@ -214,7 +214,6 @@ pt_BR: framework: banned_account_header: "Sua conta está atualmente proibida." banned_account_body: "Isso significa que você não pode gostar, informar ou escrever comentários." - because_you_ignored: "Porque você ignorou os seguintes comentadores, seus comentários estão ocultos." comment: comentário comment_is_ignored: "Este comentário está oculto porque você ignorou esse usuário." comments: comentários @@ -225,13 +224,11 @@ pt_BR: error: "Nomes de usuários podem conter números de letras e _ somente" label: "Novo usuário" msg: "Sua conta está suspensa porque seu nome de usuário foi considerado inapropriado. Para restaurar sua conta, insira um novo nome de usuário. Entre em contato conosco se você tiver alguma dúvida." - ignored_users: "Usuários ignorados" my_comments: "Meus comentários" my_profile: "Meu perfil" new_count: "Ver {0} {1}" profile: Perfil show_all_comments: "Exibir todos os comentários" - stop_ignoring: "Pare de ignorar" success_bio_update: "Sua biografia foi atualizada" success_name_update: "Seu nome de usuário foi atualizado" success_update_settings: "As alterações que você fez foram aplicadas no hilo de comentários neste artigo" diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index 2659237f3..15c8b3544 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -5,4 +5,7 @@ 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'; export {default as withEmit} from 'coral-framework/hocs/withEmit'; -export {withIgnoreUser} from 'coral-framework/graphql/mutations'; +export { + withIgnoreUser, + withStopIgnoringUser, +} from 'coral-framework/graphql/mutations'; diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.css b/plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.css new file mode 100644 index 000000000..b279101ea --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.css @@ -0,0 +1,22 @@ +.list { + display: table; + list-style-type: none; + margin-left: 0; + padding-left: 0; +} + +.listItem { + display: table-row; +} + +.username { + display: table-cell; +} + +.button { + composes: buttonReset from "coral-framework/styles/reset.css"; + + margin-left: 16px; + color: #D0011B; + text-decoration: underline; +} diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.js b/plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.js new file mode 100644 index 000000000..111568d34 --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoredUserSection.js @@ -0,0 +1,23 @@ +import React from 'react'; +import styles from './IgnoredUserSection.css'; +import {t} from 'plugin-api/beta/client/services'; + +export default ({ignoredUsers, stopIgnoringUser}) => ( +
+

{t('talk-plugin-ignore-user.section_title')}

+

{t('talk-plugin-ignore-user.section_info')}

+
    + {ignoredUsers.map(({username, id}) => ( +
  • + {username} + +
  • + ))} +
+
+); diff --git a/plugins/talk-plugin-ignore-user/client/containers/IgnoredUserSection.js b/plugins/talk-plugin-ignore-user/client/containers/IgnoredUserSection.js new file mode 100644 index 000000000..e420f180b --- /dev/null +++ b/plugins/talk-plugin-ignore-user/client/containers/IgnoredUserSection.js @@ -0,0 +1,36 @@ +import React from 'react'; +import IgnoredUserSection from '../components/IgnoredUserSection'; +import {compose, gql} from 'react-apollo'; +import {withFragments, excludeIf, withStopIgnoringUser} from 'plugin-api/beta/client/hocs'; + +class IgnoredUserSectionContainer extends React.Component { + + render() { + return ; + } +} + +const withIgnoredUserSectionFragments = withFragments({ + root: gql` + fragment TalkIgnoreUser_IgnoredUserSection_root on RootQuery { + me { + id + ignoredUsers { + id, + username, + } + } + } + `, +}); + +const enhance = compose( + withIgnoredUserSectionFragments, + withStopIgnoringUser, + excludeIf(({root: {me}}) => me.ignoredUsers.length === 0), +); + +export default enhance(IgnoredUserSectionContainer); diff --git a/plugins/talk-plugin-ignore-user/client/index.js b/plugins/talk-plugin-ignore-user/client/index.js index 79f440126..798728ed1 100644 --- a/plugins/talk-plugin-ignore-user/client/index.js +++ b/plugins/talk-plugin-ignore-user/client/index.js @@ -1,5 +1,6 @@ import IgnoreUserAction from './containers/IgnoreUserAction'; import IgnoreUserConfirmation from './containers/IgnoreUserConfirmation'; +import IgnoredUserSection from './containers/IgnoredUserSection'; import translations from './translations.yml'; import update from 'immutability-helper'; @@ -17,10 +18,26 @@ export default { } } }), + StopIgnoringUser: ({variables}) => ({ + updateQueries: { + CoralEmbedStream_Profile: (previousData) => { + const noLongerIgnoredUserId = variables.id; + + // remove noLongerIgnoredUserId from ignoredUsers + const updated = update(previousData, {me: {ignoredUsers: { + $apply: (ignoredUsers) => { + return ignoredUsers.filter((u) => u.id !== noLongerIgnoredUserId); + } + }}}); + return updated; + } + } + }), }, slots: { authorMenuActions: [IgnoreUserAction], - ignoreUserConfirmation: [IgnoreUserConfirmation] + ignoreUserConfirmation: [IgnoreUserConfirmation], + profileSections: [IgnoredUserSection], }, translations }; diff --git a/plugins/talk-plugin-ignore-user/client/translations.yml b/plugins/talk-plugin-ignore-user/client/translations.yml index 0eb07d101..a6c051ada 100644 --- a/plugins/talk-plugin-ignore-user/client/translations.yml +++ b/plugins/talk-plugin-ignore-user/client/translations.yml @@ -1,5 +1,8 @@ en: talk-plugin-ignore-user: + section_title: Ignored users + section_info: Because you ignored the following commenters, their comments are hidden. + stop_ignoring: Stop ignoring ignore_user: Ignore User cancel: Cancel confirmation: | @@ -10,3 +13,13 @@ en: confirmation_title: Ignore {0}? es: talk-plugin-ignore-user: + section_title: "Usuarios ignorados" + stop_ignoring: "No ignorar más" +fr: + talk-plugin-ignore-user: + section_title: "Utilisateurs ignorés" +pt_Br: + talk-plugin-ignore-user: + section_title: "Usuários ignorados" + section_info: "Porque você ignorou os seguintes comentadores, seus comentários estão ocultos." + stop_ignoring: "Pare de ignorar" From 77396ccc31425270854b5d4a674c14436d17dd0d Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 01:17:05 +0700 Subject: [PATCH 17/20] Fix graphql tree bug --- client/coral-embed-stream/src/containers/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/coral-embed-stream/src/containers/Comment.js b/client/coral-embed-stream/src/containers/Comment.js index 11a668371..5e2766b9a 100644 --- a/client/coral-embed-stream/src/containers/Comment.js +++ b/client/coral-embed-stream/src/containers/Comment.js @@ -93,12 +93,12 @@ const withCommentFragments = withFragments({ root: gql` fragment CoralEmbedStream_Comment_root on RootQuery { __typename - ${getSlotFragmentSpreads(slots, 'root')} me { ignoredUsers { id } } + ${getSlotFragmentSpreads(slots, 'root')} } `, asset: gql` From 943c9decbaf2a07f33dd05caf14e412c9f74524a Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 01:18:14 +0700 Subject: [PATCH 18/20] Add to default plugins --- plugins.default.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins.default.json b/plugins.default.json index 0fcc70681..950cec229 100644 --- a/plugins.default.json +++ b/plugins.default.json @@ -17,6 +17,9 @@ "talk-plugin-sort-newest", "talk-plugin-sort-oldest", "talk-plugin-sort-most-respected", - "talk-plugin-sort-most-replied" + "talk-plugin-sort-most-replied", + "talk-plugin-author-menu", + "talk-plugin-member-since", + "talk-plugin-ignore-user" ] } From a7224563598cda2f90f72684ff8b98179787f61f Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 01:25:16 +0700 Subject: [PATCH 19/20] reorder --- plugins/talk-plugin-ignore-user/client/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/talk-plugin-ignore-user/client/index.js b/plugins/talk-plugin-ignore-user/client/index.js index 798728ed1..6583f68e6 100644 --- a/plugins/talk-plugin-ignore-user/client/index.js +++ b/plugins/talk-plugin-ignore-user/client/index.js @@ -5,6 +5,12 @@ import translations from './translations.yml'; import update from 'immutability-helper'; export default { + slots: { + authorMenuActions: [IgnoreUserAction], + ignoreUserConfirmation: [IgnoreUserConfirmation], + profileSections: [IgnoredUserSection], + }, + translations, mutations: { IgnoreUser: ({variables}) => ({ updateQueries: { @@ -34,10 +40,4 @@ export default { } }), }, - slots: { - authorMenuActions: [IgnoreUserAction], - ignoreUserConfirmation: [IgnoreUserConfirmation], - profileSections: [IgnoredUserSection], - }, - translations }; From a5acf8ba82589beb2ab2ed8484e367eb782d94f2 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 5 Sep 2017 02:22:10 +0700 Subject: [PATCH 20/20] Add some global css classes --- .../client/components/AuthorName.js | 5 ++-- .../client/components/Menu.js | 8 +++--- .../client/components/IgnoreUserAction.js | 5 +++- .../components/IgnoreUserConfirmation.js | 9 ++++--- .../client/components/IgnoredUserSection.js | 2 +- .../client/components/MemberSinceInfo.js | 7 +++--- pluginsa.json | 25 +++++++++++++++++++ 7 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 pluginsa.json diff --git a/plugins/talk-plugin-author-menu/client/components/AuthorName.js b/plugins/talk-plugin-author-menu/client/components/AuthorName.js index d6e6c66d1..191f93490 100644 --- a/plugins/talk-plugin-author-menu/client/components/AuthorName.js +++ b/plugins/talk-plugin-author-menu/client/components/AuthorName.js @@ -2,13 +2,14 @@ import React from 'react'; 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, contentSlot, menuVisible, toggleMenu, hideMenu}) => { return ( -
+
); diff --git a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js index 9265dfda2..8da879f62 100644 --- a/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js +++ b/plugins/talk-plugin-ignore-user/client/components/IgnoreUserConfirmation.js @@ -1,20 +1,21 @@ import React from 'react'; import styles from './IgnoreUserConfirmation.css'; import {t} from 'plugin-api/beta/client/services'; +import cn from 'classnames'; export default ({ignoreUser, cancel, username}) => ( -