mirror of
https://github.com/wassname/talk.git
synced 2026-08-17 11:27:52 +08:00
Merge master
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: talk-plugin-viewing-options
|
||||
permalink: /plugin/talk-plugin-viewing-options/
|
||||
layout: plugin
|
||||
plugin:
|
||||
name: talk-plugin-viewing-options
|
||||
default: true
|
||||
provides:
|
||||
- Client
|
||||
---
|
||||
|
||||
Pluginizes the sorting/viewing options for a comment stream.
|
||||
@@ -0,0 +1,16 @@
|
||||
.label {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
padding: 6px 16px 6px 10px;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.input {
|
||||
cursor: pointer;
|
||||
margin-right: 6px;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import styles from './SortOption.css';
|
||||
import PropTypes from 'prop-types';
|
||||
import { PLUGIN_NAME } from '../../constants';
|
||||
|
||||
export default class SortOption extends React.Component {
|
||||
render() {
|
||||
const className = cn([
|
||||
styles.label,
|
||||
`${PLUGIN_NAME}-sort-option`,
|
||||
{ [`${PLUGIN_NAME}-sort-option-active`]: this.props.active },
|
||||
]);
|
||||
return (
|
||||
<label className={className}>
|
||||
<input
|
||||
type="radio"
|
||||
onChange={this.props.setSort}
|
||||
checked={this.props.active}
|
||||
className={styles.input}
|
||||
/>
|
||||
{this.props.label}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SortOption.propTypes = {
|
||||
// A simple callback to be called when clicking on this sort option.
|
||||
setSort: PropTypes.func.isRequired,
|
||||
|
||||
// Whether or not this sort option is active.
|
||||
active: PropTypes.bool.isRequired,
|
||||
|
||||
// Label to show next to the input control.
|
||||
label: PropTypes.string.isRequired,
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import withSortOption from 'plugin-api/beta/client/hocs/withSortOption';
|
||||
import SortOption from '../components/SortOption';
|
||||
|
||||
/**
|
||||
* A factory creating a sort option component.
|
||||
* @param {string|function} label label to display, can be a callback for lazy evaluation.
|
||||
* @param {Object} sort sort parameters
|
||||
* @param {string} sort.sortBy
|
||||
* @param {string} sort.sortOrder
|
||||
* @return {Object} Component
|
||||
*/
|
||||
export const createSortOption = (label, sort) =>
|
||||
withSortOption({ ...sort, label })(SortOption);
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Category.css';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
|
||||
@@ -8,7 +9,7 @@ const childFactory = child => (
|
||||
</li>
|
||||
);
|
||||
|
||||
const ViewingOptions = ({ slot, title, data, asset, root }) => {
|
||||
const Category = ({ slot, title, slotPassthrough }) => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.title}>{title}</div>
|
||||
@@ -17,11 +18,16 @@ const ViewingOptions = ({ slot, title, data, asset, root }) => {
|
||||
childFactory={childFactory}
|
||||
className={styles.list}
|
||||
component={'ul'}
|
||||
data={data}
|
||||
queryData={{ asset, root }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewingOptions;
|
||||
Category.propTypes = {
|
||||
slot: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Category;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './Menu.css';
|
||||
import { capitalize } from 'plugin-api/beta/client/utils';
|
||||
@@ -13,16 +14,19 @@ class Menu extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { slotPassthrough } = this.props;
|
||||
return (
|
||||
<div className={cn([styles.menu, 'talk-plugin-viewing-options-menu'])}>
|
||||
{Object.keys(this.categories).map(category => (
|
||||
<IfSlotIsNotEmpty
|
||||
slot={`viewingOptions${capitalize(category)}`}
|
||||
key={category}
|
||||
passthrough={slotPassthrough}
|
||||
>
|
||||
<Category
|
||||
slot={`viewingOptions${capitalize(category)}`}
|
||||
title={this.categories[category]}
|
||||
slotPassthrough={slotPassthrough}
|
||||
/>
|
||||
</IfSlotIsNotEmpty>
|
||||
))}
|
||||
@@ -31,4 +35,8 @@ class Menu extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
Menu.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './ViewingOptions.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
@@ -24,7 +25,7 @@ class ViewingOptions extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { open, data, root, asset } = this.props;
|
||||
const { open, slotPassthrough } = this.props;
|
||||
return (
|
||||
<ClickOutside onClickOutside={this.handleClickOutside}>
|
||||
<div className={cn([styles.root, 'talk-plugin-viewing-options'])}>
|
||||
@@ -41,11 +42,18 @@ class ViewingOptions extends React.Component {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{open && <Menu data={data} root={root} asset={asset} />}
|
||||
{open && <Menu slotPassthrough={slotPassthrough} />}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ViewingOptions.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
openMenu: PropTypes.func.isRequired,
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ViewingOptions;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const prefix = 'TALK_VIEWING_OPTIONS';
|
||||
export const PLUGIN_NAME = 'talk-plugin-viewing-options';
|
||||
|
||||
/* Contants for redux actions */
|
||||
const prefix = 'TALK_VIEWING_OPTIONS';
|
||||
export const OPEN_MENU = `${prefix}_OPEN_MENU`;
|
||||
export const CLOSE_MENU = `${prefix}_CLOSE_MENU`;
|
||||
|
||||
@@ -4,6 +4,7 @@ import ViewingOptions from '../components/ViewingOptions';
|
||||
import { openMenu, closeMenu } from '../actions';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import { getSlotFragmentSpreads } from 'plugin-api/beta/client/utils';
|
||||
import { mapProps } from 'recompose';
|
||||
|
||||
const slots = ['viewingOptionsSort', 'viewingOptionsFilter'];
|
||||
|
||||
@@ -29,7 +30,14 @@ const withViewingOptionsFragments = withFragments({
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
withViewingOptionsFragments
|
||||
withViewingOptionsFragments,
|
||||
mapProps(({ root, asset, ...rest }) => ({
|
||||
slotPassthrough: {
|
||||
root,
|
||||
asset,
|
||||
},
|
||||
...rest,
|
||||
}))
|
||||
);
|
||||
|
||||
export default enhance(ViewingOptions);
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
ar:
|
||||
talk-plugin-viewing-options:
|
||||
viewing_options: "خيارات العرض"
|
||||
sort: فرز
|
||||
filter: تصفية
|
||||
da:
|
||||
talk-plugin-viewing-options:
|
||||
viewing_options: "Viewing Options"
|
||||
|
||||
Reference in New Issue
Block a user