mirror of
https://github.com/wassname/talk.git
synced 2026-07-29 11:28:24 +08:00
Refactor talk-plugin-notifications using the new withGraphQLExtension
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import Toggle from 'talk-plugin-notifications/client/components/Toggle';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { withFragments } from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ToggleContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ onFeatured: false });
|
||||
|
||||
if (this.getOnFeaturedSetting()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.getOnFeaturedSetting(this.props);
|
||||
const nextSetting = this.getOnFeaturedSetting(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
getOnFeaturedSetting = (props = this.props) =>
|
||||
props.root.me.notificationSettings.onFeatured;
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
onFeatured: !this.getOnFeaturedSetting(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Toggle
|
||||
checked={this.getOnFeaturedSetting()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{t('talk-plugin-notifications-category-featured.toggle_description')}
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotificationsCategoryFeatured_Toggle_root on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
onFeatured
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
);
|
||||
|
||||
export default enhance(ToggleContainer);
|
||||
@@ -1,33 +0,0 @@
|
||||
import { gql } from 'react-apollo';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onFeatured === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryFeatured_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onFeatured
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onFeatured: input.onFeatured,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,11 +1,14 @@
|
||||
import Toggle from './containers/Toggle';
|
||||
import translations from './translations.yml';
|
||||
import graphql from './graphql';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
|
||||
|
||||
const SettingsToggle = createSettingsToggle('onFeatured', () =>
|
||||
t('talk-plugin-notifications-category-featured.toggle_description')
|
||||
);
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
notificationSettings: [Toggle],
|
||||
notificationSettings: [SettingsToggle],
|
||||
},
|
||||
translations,
|
||||
...graphql,
|
||||
};
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import Toggle from 'talk-plugin-notifications/client/components/Toggle';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import {
|
||||
withFragments,
|
||||
withGraphQLExtension,
|
||||
} from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ToggleContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ onReply: false });
|
||||
|
||||
if (this.getOnReplySetting()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.getOnReplySetting(this.props);
|
||||
const nextSetting = this.getOnReplySetting(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
getOnReplySetting = (props = this.props) =>
|
||||
props.root.me.notificationSettings.onReply;
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
onReply: !this.getOnReplySetting(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Toggle
|
||||
checked={this.getOnReplySetting()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{t('talk-plugin-notifications-category-reply.toggle_description')}
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const extension = {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onReply === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryReply_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onReply
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onReply: input.onReply,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotificationsCategoryReply_Toggle_root on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
onReply
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
}),
|
||||
withGraphQLExtension(extension)
|
||||
);
|
||||
|
||||
export default enhance(ToggleContainer);
|
||||
@@ -1,33 +0,0 @@
|
||||
import { gql } from 'react-apollo';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onReply === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryReply_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onReply
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onReply: input.onReply,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,8 +1,14 @@
|
||||
import Toggle from './containers/Toggle';
|
||||
import translations from './translations.yml';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
|
||||
|
||||
const SettingsToggle = createSettingsToggle('onReply', () =>
|
||||
t('talk-plugin-notifications-category-reply.toggle_description')
|
||||
);
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
notificationSettings: [Toggle],
|
||||
notificationSettings: [SettingsToggle],
|
||||
},
|
||||
translations,
|
||||
};
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import Toggle from 'talk-plugin-notifications/client/components/Toggle';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { withFragments } from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ToggleContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ onStaffReply: false });
|
||||
|
||||
if (this.getOnReplySetting()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.getOnReplySetting(this.props);
|
||||
const nextSetting = this.getOnReplySetting(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
getOnReplySetting = (props = this.props) =>
|
||||
props.root.me.notificationSettings.onStaffReply;
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
onStaffReply: !this.getOnReplySetting(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Toggle
|
||||
checked={this.getOnReplySetting()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{t('talk-plugin-notifications-category-staff.toggle_description')}
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotificationsCategoryStaffReply_User_Fragment on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
onStaffReply
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
);
|
||||
|
||||
export default enhance(ToggleContainer);
|
||||
@@ -1,33 +0,0 @@
|
||||
import { gql } from 'react-apollo';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onStaffReply === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryStaffReply_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onStaffReply
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onStaffReply: input.onStaffReply,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,11 +1,14 @@
|
||||
import Toggle from './containers/Toggle';
|
||||
import translations from './translations.yml';
|
||||
import graphql from './graphql';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
|
||||
|
||||
const SettingsToggle = createSettingsToggle('onStaffReply', () =>
|
||||
t('talk-plugin-notifications-category-staff.toggle_description')
|
||||
);
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
notificationSettings: [Toggle],
|
||||
notificationSettings: [SettingsToggle],
|
||||
},
|
||||
translations,
|
||||
...graphql,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
.title {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.disabled {
|
||||
color: #e5e5e5;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.checkBox {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Checkbox } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './Toggle.css';
|
||||
import uuid from 'uuid/v4';
|
||||
import cn from 'classnames';
|
||||
|
||||
class Toggle extends React.Component {
|
||||
id = uuid();
|
||||
|
||||
render() {
|
||||
const { checked, onChange, children, disabled } = this.props;
|
||||
return (
|
||||
<div className={styles.toggle}>
|
||||
<label
|
||||
htmlFor={this.id}
|
||||
className={cn(styles.title, { [styles.disabled]: disabled })}
|
||||
>
|
||||
{children}
|
||||
</label>
|
||||
<div className={styles.checkBox}>
|
||||
<Checkbox
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
id={this.id}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Toggle.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
checked: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default Toggle;
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Toggle } from './Toggle';
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import Toggle from '../components/Toggle';
|
||||
import withSettingsToggle from '../hocs/withSettingsToggle';
|
||||
|
||||
/**
|
||||
* createSettingsToggle will add a boolean setting with the
|
||||
* name `settingsName` to notification settings and return
|
||||
* a full Toggle Component.
|
||||
*
|
||||
* You must provide a `label` either as a string or as a callback.
|
||||
* E.g. to provide translations you could do:
|
||||
*
|
||||
* `const SettingsToggle = createSettingsToggle('onReply', () => t('translate'));`
|
||||
*/
|
||||
const createSettingsToggle = (settingsName, label) => {
|
||||
const SettingsToggle = props => (
|
||||
<Toggle {...props}>{typeof label === 'function' ? label() : label}</Toggle>
|
||||
);
|
||||
return withSettingsToggle(settingsName)(SettingsToggle);
|
||||
};
|
||||
|
||||
export default createSettingsToggle;
|
||||
@@ -0,0 +1 @@
|
||||
export { default as createSettingsToggle } from './createSettingsToggle';
|
||||
@@ -0,0 +1 @@
|
||||
export { default as withSettingsToggle } from './withSettingsToggle';
|
||||
@@ -0,0 +1,121 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import {
|
||||
withFragments,
|
||||
withGraphQLExtension,
|
||||
} from 'plugin-api/beta/client/hocs';
|
||||
|
||||
const createHOC = settingsName => WrappedComponent => {
|
||||
class WithSettingsToggle extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ [settingsName]: false });
|
||||
|
||||
if (this.isChecked()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.isChecked(this.props);
|
||||
const nextSetting = this.isChecked(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
isChecked = (props = this.props) =>
|
||||
props.root.me.notificationSettings[settingsName];
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
[settingsName]: !this.isChecked(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WrappedComponent
|
||||
checked={this.isChecked()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WithSettingsToggle.propTypes = {
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
return WithSettingsToggle;
|
||||
};
|
||||
|
||||
/**
|
||||
* withSettingsToggle will add a boolean setting with the
|
||||
* name `settingsName` to notification settings and provide
|
||||
* the folliwng props:
|
||||
*
|
||||
* `checked: boolean` Whether setting is on or off
|
||||
* `onChange: () => void` Calling this will toggle the setting
|
||||
* `disabled: boolean` Whether setting is disabled
|
||||
*/
|
||||
const withSettingsToggle = settingsName => {
|
||||
const extension = {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input[settingsName] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotifications_Toggle_${settingsName}_Fragment on User {
|
||||
notificationSettings {
|
||||
${settingsName}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
[settingsName]: input[settingsName],
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
return compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotifications_Toggle_${settingsName}_root on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
${settingsName}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
}),
|
||||
withGraphQLExtension(extension),
|
||||
createHOC(settingsName)
|
||||
);
|
||||
};
|
||||
|
||||
export default withSettingsToggle;
|
||||
Reference in New Issue
Block a user