diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js
index 397d8b94d..8b91c83de 100644
--- a/plugin-api/beta/client/hocs/index.js
+++ b/plugin-api/beta/client/hocs/index.js
@@ -6,6 +6,7 @@ export {
withEmit,
excludeIf,
withFragments,
+ withMutation,
withForgotPassword,
withSignIn,
withSignUp,
diff --git a/plugins/talk-plugin-notifications-category-reply/client/components/Toggle.js b/plugins/talk-plugin-notifications-category-reply/client/components/Toggle.js
index a9a0ff519..fa32a0880 100644
--- a/plugins/talk-plugin-notifications-category-reply/client/components/Toggle.js
+++ b/plugins/talk-plugin-notifications-category-reply/client/components/Toggle.js
@@ -6,12 +6,12 @@ import styles from './Toggle.css';
class Toggle extends React.Component {
render() {
- const { checked } = this.props;
+ const { checked, onChange } = this.props;
return (
{t('talk-plugin-notifications-category-reply.toggle_description')}
-
+
);
@@ -20,6 +20,7 @@ class Toggle extends React.Component {
Toggle.propTypes = {
checked: PropTypes.bool,
+ onChange: PropTypes.func,
};
export default Toggle;
diff --git a/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js b/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js
index 2d275e452..70812778c 100644
--- a/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js
+++ b/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js
@@ -5,14 +5,46 @@ import Toggle from '../components/Toggle';
import { withFragments } 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 ;
+ return ;
}
}
ToggleContainer.propTypes = {
data: PropTypes.object,
root: PropTypes.object,
+ indicateOn: PropTypes.func.isRequired,
+ indicateOff: PropTypes.func.isRequired,
+ setTurnOffInputFragment: PropTypes.func.isRequired,
+ updateNotificationSettings: PropTypes.func.isRequired,
};
const enhance = compose(
diff --git a/plugins/talk-plugin-notifications-category-reply/client/graphql.js b/plugins/talk-plugin-notifications-category-reply/client/graphql.js
new file mode 100644
index 000000000..2b216aa95
--- /dev/null
+++ b/plugins/talk-plugin-notifications-category-reply/client/graphql.js
@@ -0,0 +1,33 @@
+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 TalkNotifications_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 });
+ },
+ }),
+ },
+};
diff --git a/plugins/talk-plugin-notifications-category-reply/client/index.js b/plugins/talk-plugin-notifications-category-reply/client/index.js
index 38a37e6ef..1e22c3a93 100644
--- a/plugins/talk-plugin-notifications-category-reply/client/index.js
+++ b/plugins/talk-plugin-notifications-category-reply/client/index.js
@@ -1,9 +1,11 @@
import Toggle from './containers/Toggle';
import translations from './translations.yml';
+import graphql from './graphql';
export default {
slots: {
notificationSettings: [Toggle],
},
translations,
+ ...graphql,
};
diff --git a/plugins/talk-plugin-notifications/client/components/Settings.js b/plugins/talk-plugin-notifications/client/components/Settings.js
index b81b65373..91523621a 100644
--- a/plugins/talk-plugin-notifications/client/components/Settings.js
+++ b/plugins/talk-plugin-notifications/client/components/Settings.js
@@ -4,10 +4,27 @@ import { IfSlotIsNotEmpty } from 'plugin-api/beta/client/components';
import { Slot } from 'plugin-api/beta/client/components';
import { t } from 'plugin-api/beta/client/services';
import styles from './Settings.css';
+import { BareButton } from 'plugin-api/beta/client/components/ui';
class Settings extends React.Component {
+ childFactory = el => {
+ const pluginName = el.type.talkPluginName;
+ const props = {
+ indicateOn: () => this.props.indicateOn(pluginName),
+ indicateOff: () => this.props.indicateOff(pluginName),
+ };
+ return React.cloneElement(el, props);
+ };
+
render() {
- const { root } = this.props;
+ const {
+ root,
+ setTurnOffInputFragment,
+ updateNotificationSettings,
+ turnOffAll,
+ turnOffButtonDisabled,
+ } = this.props;
+
return (
@@ -16,7 +33,17 @@ class Settings extends React.Component {
{t('talk-plugin-notifications.settings_subtitle')}
-
+
+
+ {' '}
+ Turn Off All{' '}
+
@@ -26,6 +53,12 @@ class Settings extends React.Component {
Settings.propTypes = {
root: PropTypes.object,
+ indicateOn: PropTypes.func.isRequired,
+ indicateOff: PropTypes.func.isRequired,
+ setTurnOffInputFragment: PropTypes.func.isRequired,
+ updateNotificationSettings: PropTypes.func.isRequired,
+ turnOffAll: PropTypes.func.isRequired,
+ turnOffButtonDisabled: PropTypes.bool.isRequired,
};
export default Settings;
diff --git a/plugins/talk-plugin-notifications/client/containers/Settings.js b/plugins/talk-plugin-notifications/client/containers/Settings.js
index 9eb16ceee..ff07c6433 100644
--- a/plugins/talk-plugin-notifications/client/containers/Settings.js
+++ b/plugins/talk-plugin-notifications/client/containers/Settings.js
@@ -4,18 +4,53 @@ import { compose, gql } from 'react-apollo';
import Settings from '../components/Settings';
import { withFragments } from 'plugin-api/beta/client/hocs';
import { getSlotFragmentSpreads } from 'plugin-api/beta/client/utils';
+import { withUpdateNotificationSettings } from '../mutations';
const slots = ['notificationSettings'];
class SettingsContainer extends React.Component {
+ state = {
+ hasNotifications: [],
+ turnOffInput: {},
+ };
+
+ indicateOn = plugin =>
+ this.setState({
+ hasNotifications: this.state.hasNotifications.concat(plugin),
+ });
+ indicateOff = plugin =>
+ this.setState({
+ hasNotifications: this.state.hasNotifications.filter(i => i !== plugin),
+ });
+ setTurnOffInputFragment = fragment =>
+ this.setState({
+ turnOffInput: { ...this.state.turnOffInput, ...fragment },
+ });
+
+ turnOffAll = () => {
+ this.props.updateNotificationSettings(this.state.turnOffInput);
+ };
+
render() {
- return ;
+ return (
+
+ );
}
}
SettingsContainer.propTypes = {
data: PropTypes.object,
root: PropTypes.object,
+ updateNotificationSettings: PropTypes.func.isRequired,
};
const enhance = compose(
@@ -26,7 +61,8 @@ const enhance = compose(
${getSlotFragmentSpreads(slots, 'root')}
}
`,
- })
+ }),
+ withUpdateNotificationSettings
);
export default enhance(SettingsContainer);
diff --git a/plugins/talk-plugin-notifications/client/graphql.js b/plugins/talk-plugin-notifications/client/graphql.js
new file mode 100644
index 000000000..b48b63668
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/graphql.js
@@ -0,0 +1,23 @@
+import { gql } from 'react-apollo';
+
+export default {
+ fragments: {
+ UpdateNotificationSettingsResponse: gql`
+ fragment Talk_UpdateNotificationSettingsResponse on UpdateNotificationSettingsResponse {
+ errors {
+ translation_key
+ }
+ }
+ `,
+ },
+ mutations: {
+ UpdateNotificationSettings: () => ({
+ optimisticResponse: {
+ updateNotificationSettings: {
+ __typename: 'UpdateNotificationSettingsResponse',
+ errors: null,
+ },
+ },
+ }),
+ },
+};
diff --git a/plugins/talk-plugin-notifications/client/index.js b/plugins/talk-plugin-notifications/client/index.js
index 69b29888c..8d3b9a08a 100644
--- a/plugins/talk-plugin-notifications/client/index.js
+++ b/plugins/talk-plugin-notifications/client/index.js
@@ -1,9 +1,11 @@
import Settings from './containers/Settings';
import translations from './translations.yml';
+import graphql from './graphql';
export default {
slots: {
profileSettings: [Settings],
},
translations,
+ ...graphql,
};
diff --git a/plugins/talk-plugin-notifications/client/mutations.js b/plugins/talk-plugin-notifications/client/mutations.js
new file mode 100644
index 000000000..83d50fc1f
--- /dev/null
+++ b/plugins/talk-plugin-notifications/client/mutations.js
@@ -0,0 +1,23 @@
+import { withMutation } from 'plugin-api/beta/client/hocs';
+import { gql } from 'react-apollo';
+
+export const withUpdateNotificationSettings = withMutation(
+ gql`
+ mutation UpdateNotificationSettings($input: NotificationSettingsInput!) {
+ updateNotificationSettings(input: $input) {
+ ...UpdateNotificationSettingsResponse
+ }
+ }
+ `,
+ {
+ props: ({ mutate }) => ({
+ updateNotificationSettings: input => {
+ return mutate({
+ variables: {
+ input,
+ },
+ });
+ },
+ }),
+ }
+);