diff --git a/package.json b/package.json index dc688ed18d..6d32969710 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "multiselect-react-dropdown": "^2.0.25", "object-to-formdata": "^4.5.1", "path-browserify": "^1.0.1", - "pl-api": "^0.0.6", + "pl-api": "^0.0.7", "postcss": "^8.4.29", "process": "^0.11.10", "punycode": "^2.1.1", diff --git a/src/actions/import-data.ts b/src/actions/import-data.ts index 9570d41fe1..b93896614c 100644 --- a/src/actions/import-data.ts +++ b/src/actions/import-data.ts @@ -38,10 +38,10 @@ const messages = defineMessages({ mutesSuccess: { id: 'import_data.success.mutes', defaultMessage: 'Mutes imported successfully' }, }); -const importFollows = (list: File | string) => +const importFollows = (list: File | string, overwrite?: boolean) => (dispatch: React.Dispatch, getState: () => RootState) => { dispatch({ type: IMPORT_FOLLOWS_REQUEST }); - return getClient(getState).settings.importFollows(list).then(response => { + return getClient(getState).settings.importFollows(list, overwrite ? 'overwrite' : 'merge').then(response => { toast.success(messages.followersSuccess); dispatch({ type: IMPORT_FOLLOWS_SUCCESS, response }); }).catch(error => { @@ -49,10 +49,10 @@ const importFollows = (list: File | string) => }); }; -const importBlocks = (list: File | string) => +const importBlocks = (list: File | string, overwrite?: boolean) => (dispatch: React.Dispatch, getState: () => RootState) => { dispatch({ type: IMPORT_BLOCKS_REQUEST }); - return getClient(getState).settings.importBlocks(list).then(response => { + return getClient(getState).settings.importBlocks(list, overwrite ? 'overwrite' : 'merge').then(response => { toast.success(messages.blocksSuccess); dispatch({ type: IMPORT_BLOCKS_SUCCESS, response }); }).catch(error => { diff --git a/src/features/edit-profile/index.tsx b/src/features/edit-profile/index.tsx index e613395f03..0efb36c492 100644 --- a/src/features/edit-profile/index.tsx +++ b/src/features/edit-profile/index.tsx @@ -133,7 +133,7 @@ const accountToCredentials = (account: Account): AccountCredentials => { note: account.__meta.source?.note ?? '', fields_attributes: [...account.__meta.source?.fields ?? []], stranger_notifications: account.__meta.pleroma?.notification_settings?.block_from_strangers === true, - accepts_email_list: account.__meta.pleroma.accepts_email_list === true, + accepts_email_list: account.__meta.pleroma?.accepts_email_list === true, hide_followers: hideNetwork, hide_follows: hideNetwork, hide_followers_count: hideNetwork, diff --git a/src/features/import-data/components/data-importer.tsx b/src/features/import-data/components/data-importer.tsx index df151b2e5f..35132c145b 100644 --- a/src/features/import-data/components/data-importer.tsx +++ b/src/features/import-data/components/data-importer.tsx @@ -1,8 +1,9 @@ import React, { useState } from 'react'; -import { MessageDescriptor, useIntl } from 'react-intl'; +import { FormattedMessage, MessageDescriptor, useIntl } from 'react-intl'; -import { Button, FileInput, Form, FormActions, FormGroup, Text } from 'soapbox/components/ui'; -import { useAppDispatch } from 'soapbox/hooks'; +import List, { ListItem } from 'soapbox/components/list'; +import { Button, FileInput, Form, FormActions, FormGroup, Text, Toggle } from 'soapbox/components/ui'; +import { useAppDispatch, useFeatures } from 'soapbox/hooks'; import type { AppDispatch, RootState } from 'soapbox/store'; @@ -12,20 +13,23 @@ interface IDataImporter { input_hint: MessageDescriptor; submit: MessageDescriptor; }; - action: (list: File | string) => (dispatch: AppDispatch, getState: () => RootState) => Promise; + action: (list: File | string, overwrite?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => Promise; accept?: string; + allowOverwrite?: boolean; } -const DataImporter: React.FC = ({ messages, action, accept = '.csv,text/csv' }) => { +const DataImporter: React.FC = ({ messages, action, accept = '.csv,text/csv', allowOverwrite }) => { const dispatch = useAppDispatch(); const intl = useIntl(); + const features = useFeatures(); const [isLoading, setIsLoading] = useState(false); const [file, setFile] = useState(null); + const [overwrite, setOverwrite] = useState(false); const handleSubmit: React.FormEventHandler = (event) => { setIsLoading(true); - dispatch(action(file!)).then(() => { + dispatch(action(file!, overwrite)).then(() => { setIsLoading(false); }).catch(() => { setIsLoading(false); @@ -51,6 +55,20 @@ const DataImporter: React.FC = ({ messages, action, accept = '.cs required /> + + {features.importOverwrite && ( + + } + > + setOverwrite(target.checked)} + /> + + + )} +