diff --git a/app/soapbox/features/chats/components/chat-page/components/welcome.tsx b/app/soapbox/features/chats/components/chat-page/components/welcome.tsx index 71ee035825..ff545b825f 100644 --- a/app/soapbox/features/chats/components/chat-page/components/welcome.tsx +++ b/app/soapbox/features/chats/components/chat-page/components/welcome.tsx @@ -1,11 +1,9 @@ -import { useMutation } from '@tanstack/react-query'; import React, { useState } from 'react'; -import { patchMeSuccess } from 'soapbox/actions/me'; -import snackbar from 'soapbox/actions/snackbar'; import List, { ListItem } from 'soapbox/components/list'; import { Button, CardBody, CardTitle, Form, Stack, Toggle } from 'soapbox/components/ui'; -import { useApi, useAppDispatch, useOwnAccount } from 'soapbox/hooks'; +import { useOwnAccount } from 'soapbox/hooks'; +import { useUpdateCredentials } from 'soapbox/queries/accounts'; type FormData = { accepting_messages?: boolean @@ -14,28 +12,17 @@ type FormData = { const Welcome = () => { const account = useOwnAccount(); - const api = useApi(); - const dispatch = useAppDispatch(); + const updateCredentials = useUpdateCredentials(); const [data, setData] = useState({ chats_onboarded: true, accepting_messages: account?.accepting_messages, }); - const updateSettings = useMutation(() => api.patch('/api/v1/accounts/update_credentials', data), { - onSuccess(response) { - dispatch(patchMeSuccess(response.data)); - dispatch(snackbar.success('Chat Settings updated successfully')); - }, - onError() { - dispatch(snackbar.success('Chat Settings failed to update.')); - }, - }); - const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); - updateSettings.mutate(); + updateCredentials.mutate(data); }; return ( diff --git a/app/soapbox/features/settings/components/messages-settings.tsx b/app/soapbox/features/settings/components/messages-settings.tsx new file mode 100644 index 0000000000..c96dc14689 --- /dev/null +++ b/app/soapbox/features/settings/components/messages-settings.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { defineMessages, useIntl } from 'react-intl'; + +import List, { ListItem } from 'soapbox/components/list'; +import { Toggle } from 'soapbox/components/ui'; +import { useOwnAccount } from 'soapbox/hooks'; +import { useUpdateCredentials } from 'soapbox/queries/accounts'; + +const messages = defineMessages({ + label: { id: 'settings.messages.label', defaultMessage: 'Allow others to message me' }, + hint: { id: 'settings.messages.hint', defaultMessage: 'Only people I follow can send me messages' }, +}); + +const MessagesSettings = () => { + const account = useOwnAccount(); + const intl = useIntl(); + const updateCredentials = useUpdateCredentials(); + + const handleChange = (event: React.ChangeEvent) => { + updateCredentials.mutate({ accepting_messages: event.target.checked }); + }; + + if (!account) { + return null; + } + + return ( + + + + + + ); +}; + +export default MessagesSettings; \ No newline at end of file diff --git a/app/soapbox/features/settings/index.tsx b/app/soapbox/features/settings/index.tsx index b8a7a33ec7..ca6be98bc8 100644 --- a/app/soapbox/features/settings/index.tsx +++ b/app/soapbox/features/settings/index.tsx @@ -11,6 +11,8 @@ import { getFeatures } from 'soapbox/utils/features'; import Preferences from '../preferences'; +import MessagesSettings from './components/messages-settings'; + const messages = defineMessages({ settings: { id: 'settings.settings', defaultMessage: 'Settings' }, profile: { id: 'settings.profile', defaultMessage: 'Profile' }, @@ -99,6 +101,13 @@ const Settings = () => { )} + + + + + + + diff --git a/app/soapbox/queries/accounts.ts b/app/soapbox/queries/accounts.ts index 7c1e1b106c..228c9a2b1e 100644 --- a/app/soapbox/queries/accounts.ts +++ b/app/soapbox/queries/accounts.ts @@ -1,3 +1,9 @@ +import { useMutation } from '@tanstack/react-query'; + +import { patchMeSuccess } from 'soapbox/actions/me'; +import snackbar from 'soapbox/actions/snackbar'; +import { useApi, useAppDispatch, useOwnAccount } from 'soapbox/hooks'; + export type IAccount = { acct: string avatar: string @@ -21,4 +27,34 @@ export type IAccount = { username: string verified: boolean website: string -} \ No newline at end of file +} + +type UpdateCredentialsData = { + accepting_messages?: boolean + chats_onboarded?: boolean +} + +const useUpdateCredentials = () => { + const account = useOwnAccount(); + const api = useApi(); + const dispatch = useAppDispatch(); + + return useMutation((data: UpdateCredentialsData) => api.patch('/api/v1/accounts/update_credentials', data), { + onMutate(variables) { + const cachedAccount = account?.toJS(); + dispatch(patchMeSuccess({ ...cachedAccount, ...variables })); + + return { cachedAccount }; + }, + onSuccess(response) { + dispatch(patchMeSuccess(response.data)); + dispatch(snackbar.success('Chat Settings updated successfully')); + }, + onError(_error, _variables, context: any) { + dispatch(snackbar.error('Chat Settings failed to update.')); + dispatch(patchMeSuccess(context.cachedAccount)); + }, + }); +}; + +export { useUpdateCredentials }; \ No newline at end of file