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] - } + }, };