Support data import on GoToSocial
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
e73341d1a9
commit
2bc0d52eff
8 changed files with 44 additions and 22 deletions
|
@ -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",
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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' />
|
||||
)}
|
||||
|
||||
|
|
|
@ -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} />}
|
||||
|
|
|
@ -8390,10 +8390,10 @@ pkg-types@^1.0.3:
|
|||
mlly "^1.2.0"
|
||||
pathe "^1.1.0"
|
||||
|
||||
pl-api@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.6.tgz#9f5c59e68666376e973403419a0d82ab322869e1"
|
||||
integrity sha512-jSM+GkxeQW31A/cnCtX5E7SBhZy3nh7iHKvcqebSZJFH/LKpkpsaFbH6oNWsr5IWMX5uAJAW2W8u/VsaoOev/g==
|
||||
pl-api@^0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-0.0.7.tgz#603dbe8d0c2b8ec0e500fe5eae26e30d77f958ba"
|
||||
integrity sha512-8Wh+uIyfcHhLLOT9s8i/Rjh/vcmjio7OEqNsUbYpJD/9n4TgW1zj/hOImlqGFDhGVdteAUx9cVr4jjQbLhtG/A==
|
||||
dependencies:
|
||||
blurhash "^2.0.5"
|
||||
http-link-header "^1.1.3"
|
||||
|
|
Loading…
Reference in a new issue