mirror of
https://github.com/wassname/talk.git
synced 2026-07-20 12:40:47 +08:00
Implement talk-plugin-author-menu
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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/*
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -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"] }]
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
.root {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.button {
|
||||
composes: buttonReset from "coral-framework/styles/reset.css";
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<ClickOutside onClickOutside={hideMenu}>
|
||||
<div className={styles.root}>
|
||||
<button
|
||||
className={styles.button}
|
||||
onClick={toggleMenu}
|
||||
>
|
||||
<span className={styles.name}>
|
||||
{comment.user.username}
|
||||
</span>
|
||||
</button>
|
||||
{menuVisible &&
|
||||
<Menu
|
||||
data={data}
|
||||
root={root}
|
||||
asset={asset}
|
||||
comment={comment}
|
||||
contentSlot={contentSlot}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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}) => (
|
||||
<div className={styles.menu}>
|
||||
<Slot
|
||||
fill={'authorMenuInfos'}
|
||||
data={data}
|
||||
queryData={{asset, root, comment}}
|
||||
/>
|
||||
<Slot
|
||||
fill={'authorMenuActions'}
|
||||
data={data}
|
||||
queryData={{asset, root, comment}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -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`;
|
||||
|
||||
@@ -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 <AuthorName
|
||||
data={this.props.data}
|
||||
root={this.props.root}
|
||||
asset={this.props.asset}
|
||||
comment={this.props.comment}
|
||||
menuVisible={this.state.menuVisible}
|
||||
toggleMenu={this.toggleMenu}
|
||||
hideMenu={this.hideMenu}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
en:
|
||||
talk-plugin-author-menu:
|
||||
es:
|
||||
talk-plugin-author-menu:
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = {};
|
||||
@@ -5,5 +5,5 @@ export default {
|
||||
translations,
|
||||
slots: {
|
||||
commentReactions: [LikeButton]
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user