Support data import on GoToSocial

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak
2024-08-19 19:41:38 +02:00
parent e73341d1a9
commit 2bc0d52eff
8 changed files with 44 additions and 22 deletions

View File

@@ -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<ImportDataActions>, 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<ImportDataActions>, 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 => {

View File

@@ -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,

View File

@@ -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<void>;
action: (list: File | string, overwrite?: boolean) => (dispatch: AppDispatch, getState: () => RootState) => Promise<void>;
accept?: string;
allowOverwrite?: boolean;
}
const DataImporter: React.FC<IDataImporter> = ({ messages, action, accept = '.csv,text/csv' }) => {
const DataImporter: React.FC<IDataImporter> = ({ 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<File | null | undefined>(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<IDataImporter> = ({ messages, action, accept = '.cs
required
/>
</FormGroup>
{features.importOverwrite && (
<List>
<ListItem
label={<FormattedMessage id='import_data.overwrite' defaultMessage='Overwrite instead of appending' />}
>
<Toggle
checked={overwrite}
onChange={({ target }) => setOverwrite(target.checked)}
/>
</ListItem>
</List>
)}
<FormActions>
<Button type='submit' theme='primary' disabled={isLoading}>
{intl.formatMessage(messages.submit)}

View File

@@ -7,6 +7,7 @@ import {
importMutes,
} from 'soapbox/actions/import-data';
import { Column } from 'soapbox/components/ui';
import { useFeatures } from 'soapbox/hooks';
import DataImporter from './components/data-importer';
@@ -35,12 +36,13 @@ const muteMessages = defineMessages({
const ImportData = () => {
const intl = useIntl();
const features = useFeatures();
return (
<Column label={intl.formatMessage(messages.heading)}>
<DataImporter action={importFollows} messages={followMessages} />
<DataImporter action={importBlocks} messages={blockMessages} />
<DataImporter action={importMutes} messages={muteMessages} />
{features.importFollows && <DataImporter action={importFollows} messages={followMessages} allowOverwrite />}
{features.importBlocks && <DataImporter action={importBlocks} messages={blockMessages} allowOverwrite />}
{features.importMutes && <DataImporter action={importMutes} messages={muteMessages} />}
</Column>
);
};

View File

@@ -140,7 +140,9 @@ const Settings = () => {
</CardBody>
{any([
features.importData,
features.importBlocks,
features.importFollows,
features.importMutes,
features.exportData,
features.accountBackups,
features.federating && features.accountMoving,
@@ -154,7 +156,7 @@ const Settings = () => {
<CardBody>
<List>
{features.importData && (
{(features.importBlocks || features.importFollows || features.importMutes) && (
<ListItem label={intl.formatMessage(messages.importData)} to='/settings/import' />
)}

View File

@@ -288,7 +288,7 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
<WrappedRoute path='/settings/profile' page={DefaultPage} component={EditProfile} content={children} />
{features.exportData && <WrappedRoute path='/settings/export' page={DefaultPage} component={ExportData} content={children} />}
{features.importData && <WrappedRoute path='/settings/import' page={DefaultPage} component={ImportData} content={children} />}
{(features.importBlocks || features.importFollows || features.importMutes) && <WrappedRoute path='/settings/import' page={DefaultPage} component={ImportData} content={children} />}
{features.manageAccountAliases && <WrappedRoute path='/settings/aliases' page={DefaultPage} component={Aliases} content={children} />}
{features.accountMoving && <WrappedRoute path='/settings/migration' page={DefaultPage} component={Migration} content={children} />}
{features.accountBackups && <WrappedRoute path='/settings/backups' page={DefaultPage} component={Backups} content={children} />}