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