118 lines
3.8 KiB
TypeScript
118 lines
3.8 KiB
TypeScript
import { type CreateAccountParams, type Relationship } from 'pl-api';
|
|
|
|
import { batcher } from 'pl-fe/api/batcher';
|
|
import { queryClient } from 'pl-fe/queries/client';
|
|
import { selectAccount } from 'pl-fe/selectors';
|
|
import { isLoggedIn } from 'pl-fe/utils/auth';
|
|
|
|
import { getClient, type PlfeResponse } from '../api';
|
|
|
|
import { importEntities } from './importer';
|
|
|
|
import type { MinifiedStatus } from 'pl-fe/reducers/statuses';
|
|
import type { AppDispatch, RootState } from 'pl-fe/store';
|
|
import type { History } from 'pl-fe/types/history';
|
|
|
|
const ACCOUNT_BLOCK_SUCCESS = 'ACCOUNT_BLOCK_SUCCESS' as const;
|
|
const ACCOUNT_MUTE_SUCCESS = 'ACCOUNT_MUTE_SUCCESS' as const;
|
|
|
|
const maybeRedirectLogin = (error: { response: PlfeResponse }, history?: History) => {
|
|
// The client is unauthorized - redirect to login.
|
|
if (history && error?.response?.status === 401) {
|
|
history.push('/login');
|
|
}
|
|
};
|
|
|
|
const createAccount = (params: CreateAccountParams) =>
|
|
async (dispatch: AppDispatch, getState: () => RootState) =>
|
|
getClient(getState()).settings.createAccount(params).then((response) =>
|
|
({ params, response }),
|
|
);
|
|
|
|
const fetchAccount = (accountId: string) =>
|
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
dispatch(fetchRelationships([accountId]));
|
|
|
|
const account = selectAccount(getState(), accountId);
|
|
|
|
if (account) {
|
|
return Promise.resolve(null);
|
|
}
|
|
|
|
return getClient(getState()).accounts.getAccount(accountId)
|
|
.then(response => {
|
|
dispatch(importEntities({ accounts: [response] }));
|
|
})
|
|
.catch(error => {
|
|
});
|
|
};
|
|
|
|
const fetchAccountByUsername = (username: string, history?: History) =>
|
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
const { auth, me } = getState();
|
|
const features = auth.client.features;
|
|
|
|
if (features.accountByUsername && (me || !features.accountLookup)) {
|
|
return getClient(getState()).accounts.getAccount(username).then(response => {
|
|
dispatch(fetchRelationships([response.id]));
|
|
dispatch(importEntities({ accounts: [response] }));
|
|
});
|
|
} else if (features.accountLookup) {
|
|
return dispatch(accountLookup(username)).then(account => {
|
|
dispatch(fetchRelationships([account.id]));
|
|
}).catch(error => {
|
|
maybeRedirectLogin(error, history);
|
|
});
|
|
} else {
|
|
return getClient(getState()).accounts.searchAccounts(username, { resolve: true, limit: 1 }).then(accounts => {
|
|
const found = accounts.find((a) => a.acct === username);
|
|
|
|
if (found) {
|
|
dispatch(fetchRelationships([found.id]));
|
|
} else {
|
|
throw accounts;
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
const fetchRelationships = (accountIds: string[]) =>
|
|
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
if (!isLoggedIn(getState)) return null;
|
|
|
|
const newAccountIds = accountIds.filter(id => !queryClient.getQueryData(['accountRelationships', id]));
|
|
|
|
if (newAccountIds.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
const fetcher = batcher.relationships(getClient(getState())).fetch;
|
|
|
|
return Promise.all(newAccountIds.map(fetcher))
|
|
.then(response => dispatch(importEntities({ relationships: response })));
|
|
};
|
|
|
|
const accountLookup = (acct: string, signal?: AbortSignal) =>
|
|
(dispatch: AppDispatch, getState: () => RootState) =>
|
|
getClient(getState()).accounts.lookupAccount(acct, { signal }).then((account) => {
|
|
if (account && account.id) dispatch(importEntities({ accounts: [account] }));
|
|
return account;
|
|
});
|
|
|
|
type AccountsAction = {
|
|
type: typeof ACCOUNT_BLOCK_SUCCESS | typeof ACCOUNT_MUTE_SUCCESS;
|
|
relationship: Relationship;
|
|
statuses: Record<string, MinifiedStatus>;
|
|
};
|
|
|
|
export {
|
|
ACCOUNT_BLOCK_SUCCESS,
|
|
ACCOUNT_MUTE_SUCCESS,
|
|
createAccount,
|
|
fetchAccount,
|
|
fetchAccountByUsername,
|
|
fetchRelationships,
|
|
accountLookup,
|
|
type AccountsAction,
|
|
};
|