Merge branch 'develop' into frontend-rw
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
commit
734e1db380
42 changed files with 279 additions and 369 deletions
|
@ -1,13 +1,12 @@
|
|||
import { staticFetch } from '../api';
|
||||
|
||||
import type { RootState } from 'pl-fe/store';
|
||||
import type { AnyAction } from 'redux';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
const FETCH_ABOUT_PAGE_REQUEST = 'FETCH_ABOUT_PAGE_REQUEST' as const;
|
||||
const FETCH_ABOUT_PAGE_SUCCESS = 'FETCH_ABOUT_PAGE_SUCCESS' as const;
|
||||
const FETCH_ABOUT_PAGE_FAIL = 'FETCH_ABOUT_PAGE_FAIL' as const;
|
||||
|
||||
const fetchAboutPage = (slug = 'index', locale?: string) => (dispatch: React.Dispatch<AnyAction>, getState: () => RootState) => {
|
||||
const fetchAboutPage = (slug = 'index', locale?: string) => (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch({ type: FETCH_ABOUT_PAGE_REQUEST, slug, locale });
|
||||
|
||||
const filename = `${slug}${locale ? `.${locale}` : ''}.html`;
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import { importEntities } from 'pl-fe/entity-store/actions';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
import { importEntities } from 'pl-fe/actions/importer';
|
||||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import type { RootState } from 'pl-fe/store';
|
||||
import type { AnyAction } from 'redux';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
const submitAccountNote = (accountId: string, value: string) =>
|
||||
(dispatch: React.Dispatch<AnyAction>, getState: () => RootState) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) =>
|
||||
getClient(getState).accounts.updateAccountNote(accountId, value)
|
||||
.then(response => dispatch(importEntities([response], Entities.RELATIONSHIPS)));
|
||||
.then(response => dispatch(importEntities({ relationships: [response] })));
|
||||
|
||||
export { submitAccountNote };
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { PLEROMA, type UpdateNotificationSettingsParams, type Account, type CreateAccountParams, type PaginatedResponse, type Relationship } from 'pl-api';
|
||||
|
||||
import { importEntities } from 'pl-fe/entity-store/actions';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
import { selectAccount } from 'pl-fe/selectors';
|
||||
import { isLoggedIn } from 'pl-fe/utils/auth';
|
||||
|
||||
import { getClient, type PlfeResponse } from '../api';
|
||||
|
||||
import { importFetchedAccount, importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
import type { MinifiedStatus } from 'pl-fe/reducers/statuses';
|
||||
|
@ -100,7 +99,7 @@ const fetchAccount = (accountId: string) =>
|
|||
|
||||
return getClient(getState()).accounts.getAccount(accountId)
|
||||
.then(response => {
|
||||
dispatch(importFetchedAccount(response));
|
||||
dispatch(importEntities({ accounts: [response] }));
|
||||
dispatch(fetchAccountSuccess(response));
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -116,7 +115,7 @@ const fetchAccountByUsername = (username: string, history?: History) =>
|
|||
if (features.accountByUsername && (me || !features.accountLookup)) {
|
||||
return getClient(getState()).accounts.getAccount(username).then(response => {
|
||||
dispatch(fetchRelationships([response.id]));
|
||||
dispatch(importFetchedAccount(response));
|
||||
dispatch(importEntities({ accounts: [response] }));
|
||||
dispatch(fetchAccountSuccess(response));
|
||||
}).catch(error => {
|
||||
dispatch(fetchAccountFail(null, error));
|
||||
|
@ -170,7 +169,7 @@ const blockAccount = (accountId: string) =>
|
|||
|
||||
return getClient(getState).filtering.blockAccount(accountId)
|
||||
.then(response => {
|
||||
dispatch(importEntities([response], Entities.RELATIONSHIPS));
|
||||
dispatch(importEntities({ relationships: [response] }));
|
||||
// Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
|
||||
return dispatch(blockAccountSuccess(response, getState().statuses));
|
||||
}).catch(error => dispatch(blockAccountFail(error)));
|
||||
|
@ -182,7 +181,7 @@ const unblockAccount = (accountId: string) =>
|
|||
|
||||
return getClient(getState).filtering.unblockAccount(accountId)
|
||||
.then(response => {
|
||||
dispatch(importEntities([response], Entities.RELATIONSHIPS));
|
||||
dispatch(importEntities({ relationships: [response] }));
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -226,7 +225,7 @@ const muteAccount = (accountId: string, notifications?: boolean, duration = 0) =
|
|||
|
||||
return client.filtering.muteAccount(accountId, params)
|
||||
.then(response => {
|
||||
dispatch(importEntities([response], Entities.RELATIONSHIPS));
|
||||
dispatch(importEntities({ relationships: [response] }));
|
||||
// Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers
|
||||
return dispatch(muteAccountSuccess(response, getState().statuses));
|
||||
})
|
||||
|
@ -238,7 +237,7 @@ const unmuteAccount = (accountId: string) =>
|
|||
if (!isLoggedIn(getState)) return null;
|
||||
|
||||
return getClient(getState()).filtering.unmuteAccount(accountId)
|
||||
.then(response => dispatch(importEntities([response], Entities.RELATIONSHIPS)));
|
||||
.then(response => dispatch(importEntities({ relationships: [response] })));
|
||||
};
|
||||
|
||||
const muteAccountRequest = (accountId: string) => ({
|
||||
|
@ -263,7 +262,7 @@ const removeFromFollowers = (accountId: string) =>
|
|||
if (!isLoggedIn(getState)) return null;
|
||||
|
||||
return getClient(getState()).accounts.removeAccountFromFollowers(accountId)
|
||||
.then(response => dispatch(importEntities([response], Entities.RELATIONSHIPS)));
|
||||
.then(response => dispatch(importEntities({ relationships: [response] })));
|
||||
};
|
||||
|
||||
const fetchRelationships = (accountIds: string[]) =>
|
||||
|
@ -278,7 +277,7 @@ const fetchRelationships = (accountIds: string[]) =>
|
|||
}
|
||||
|
||||
return getClient(getState()).accounts.getRelationships(newAccountIds)
|
||||
.then(response => dispatch(importEntities(response, Entities.RELATIONSHIPS)));
|
||||
.then(response => dispatch(importEntities({ relationships: response })));
|
||||
};
|
||||
|
||||
const fetchFollowRequests = () =>
|
||||
|
@ -289,7 +288,7 @@ const fetchFollowRequests = () =>
|
|||
|
||||
return getClient(getState()).myAccount.getFollowRequests()
|
||||
.then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(fetchFollowRequestsSuccess(response.items, response.next));
|
||||
})
|
||||
.catch(error => dispatch(fetchFollowRequestsFail(error)));
|
||||
|
@ -321,7 +320,7 @@ const expandFollowRequests = () =>
|
|||
dispatch(expandFollowRequestsRequest());
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(expandFollowRequestsSuccess(response.items, response.next));
|
||||
}).catch(error => dispatch(expandFollowRequestsFail(error)));
|
||||
};
|
||||
|
@ -400,7 +399,7 @@ const pinAccount = (accountId: string) =>
|
|||
if (!isLoggedIn(getState)) return dispatch(noOp);
|
||||
|
||||
return getClient(getState).accounts.pinAccount(accountId).then(response =>
|
||||
dispatch(importEntities([response], Entities.RELATIONSHIPS)),
|
||||
dispatch(importEntities({ relationships: [response] })),
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -409,7 +408,7 @@ const unpinAccount = (accountId: string) =>
|
|||
if (!isLoggedIn(getState)) return dispatch(noOp);
|
||||
|
||||
return getClient(getState).accounts.unpinAccount(accountId).then(response =>
|
||||
dispatch(importEntities([response], Entities.RELATIONSHIPS)),
|
||||
dispatch(importEntities({ relationships: [response] })),
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -429,7 +428,7 @@ const fetchPinnedAccounts = (accountId: string) =>
|
|||
dispatch(fetchPinnedAccountsRequest(accountId));
|
||||
|
||||
return getClient(getState).accounts.getAccountEndorsements(accountId).then(response => {
|
||||
dispatch(importFetchedAccounts(response));
|
||||
dispatch(importEntities({ accounts: response }));
|
||||
dispatch(fetchPinnedAccountsSuccess(accountId, response, null));
|
||||
}).catch(error => {
|
||||
dispatch(fetchPinnedAccountsFail(accountId, error));
|
||||
|
@ -458,7 +457,7 @@ const accountSearch = (q: string, signal?: AbortSignal) =>
|
|||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch({ type: ACCOUNT_SEARCH_REQUEST, params: { q } });
|
||||
return getClient(getState()).accounts.searchAccounts(q, { resolve: false, limit: 4, following: true }, { signal }).then((accounts) => {
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importEntities({ accounts }));
|
||||
dispatch({ type: ACCOUNT_SEARCH_SUCCESS, accounts });
|
||||
return accounts;
|
||||
}).catch(error => {
|
||||
|
@ -471,7 +470,7 @@ const accountLookup = (acct: string, signal?: AbortSignal) =>
|
|||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch({ type: ACCOUNT_LOOKUP_REQUEST, acct });
|
||||
return getClient(getState()).accounts.lookupAccount(acct, { signal }).then((account) => {
|
||||
if (account && account.id) dispatch(importFetchedAccount(account));
|
||||
if (account && account.id) dispatch(importEntities({ accounts: [account] }));
|
||||
dispatch({ type: ACCOUNT_LOOKUP_SUCCESS, account });
|
||||
return account;
|
||||
}).catch(error => {
|
||||
|
@ -489,7 +488,7 @@ const fetchBirthdayReminders = (month: number, day: number) =>
|
|||
dispatch({ type: BIRTHDAY_REMINDERS_FETCH_REQUEST, day, month, accountId: me });
|
||||
|
||||
return getClient(getState).accounts.getBirthdays(day, month).then(response => {
|
||||
dispatch(importFetchedAccounts(response));
|
||||
dispatch(importEntities({ accounts: response }));
|
||||
dispatch({
|
||||
type: BIRTHDAY_REMINDERS_FETCH_SUCCESS,
|
||||
accounts: response,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { fetchRelationships } from 'pl-fe/actions/accounts';
|
||||
import { importFetchedAccount, importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from 'pl-fe/actions/importer';
|
||||
import { importEntities } from 'pl-fe/actions/importer';
|
||||
import { filterBadges, getTagDiff } from 'pl-fe/utils/badges';
|
||||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { deleteFromTimelines } from './timelines';
|
||||
|
||||
import type { Account, AdminGetAccountsParams, AdminGetReportsParams, PleromaConfig } from 'pl-api';
|
||||
import type { Account, AdminGetAccountsParams, AdminGetReportsParams, PleromaConfig, Status } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
const ADMIN_CONFIG_FETCH_REQUEST = 'ADMIN_CONFIG_FETCH_REQUEST' as const;
|
||||
|
@ -111,9 +111,7 @@ const fetchReports = (params?: AdminGetReportsParams) =>
|
|||
return getClient(state).admin.reports.getReports(params)
|
||||
.then(({ items }) => {
|
||||
items.forEach((report) => {
|
||||
if (report.account?.account) dispatch(importFetchedAccount(report.account.account));
|
||||
if (report.target_account?.account) dispatch(importFetchedAccount(report.target_account.account));
|
||||
dispatch(importFetchedStatuses(report.statuses));
|
||||
dispatch(importEntities({ statuses: report.statuses as Array<Status>, accounts: [report.account?.account, report.target_account?.account] }));
|
||||
dispatch({ type: ADMIN_REPORTS_FETCH_SUCCESS, reports: items, params });
|
||||
});
|
||||
}).catch(error => {
|
||||
|
@ -141,7 +139,7 @@ const fetchUsers = (params?: AdminGetAccountsParams) =>
|
|||
dispatch({ type: ADMIN_USERS_FETCH_REQUEST, params });
|
||||
|
||||
return getClient(state).admin.accounts.getAccounts(params).then((res) => {
|
||||
dispatch(importFetchedAccounts(res.items.map(({ account }) => account).filter((account): account is Account => account !== null)));
|
||||
dispatch(importEntities({ accounts: res.items.map(({ account }) => account).filter((account): account is Account => account !== null) }));
|
||||
dispatch(fetchRelationships(res.items.map((account) => account.id)));
|
||||
dispatch({ type: ADMIN_USERS_FETCH_SUCCESS, users: res.items, params, next: res.next });
|
||||
return res;
|
||||
|
@ -203,7 +201,7 @@ const toggleStatusSensitivity = (statusId: string, sensitive: boolean) =>
|
|||
dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_REQUEST, statusId });
|
||||
return getClient(getState).admin.statuses.updateStatus(statusId, { sensitive: !sensitive })
|
||||
.then((status) => {
|
||||
dispatch(importFetchedStatus(status));
|
||||
dispatch(importEntities({ statuses: [status] }));
|
||||
dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_SUCCESS, statusId, status });
|
||||
}).catch(error => {
|
||||
dispatch({ type: ADMIN_STATUS_TOGGLE_SENSITIVITY_FAIL, error, statusId });
|
||||
|
|
|
@ -5,7 +5,7 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account as BaseAccount } from 'pl-api';
|
||||
import type { Account } from 'pl-fe/normalizers/account';
|
||||
|
@ -63,7 +63,7 @@ const fetchAliasesSuggestions = (q: string) =>
|
|||
|
||||
return getClient(getState()).accounts.searchAccounts(q, { resolve: true, limit: 4 })
|
||||
.then((data) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
dispatch(importEntities({ accounts: data }));
|
||||
dispatch(fetchAliasesSuggestionsReady(q, data));
|
||||
}).catch(error => toast.showAlertForError(error));
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ import { isStandalone } from 'pl-fe/utils/state';
|
|||
|
||||
import { type PlfeResponse, getClient } from '../api';
|
||||
|
||||
import { importFetchedAccount } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
|
@ -150,7 +150,7 @@ const verifyCredentials = (token: string, accountUrl?: string) =>
|
|||
const client = new PlApiClient(baseURL, token);
|
||||
|
||||
return client.settings.verifyCredentials().then((account) => {
|
||||
dispatch(importFetchedAccount(account));
|
||||
dispatch(importEntities({ accounts: [account] }));
|
||||
dispatch({ type: VERIFY_CREDENTIALS_SUCCESS, token, account });
|
||||
if (account.id === getState().me) dispatch(fetchMeSuccess(account));
|
||||
return account;
|
||||
|
@ -159,7 +159,7 @@ const verifyCredentials = (token: string, accountUrl?: string) =>
|
|||
// The user is waitlisted
|
||||
const account = error.response.json;
|
||||
const parsedAccount = v.parse(credentialAccountSchema, error.response.json);
|
||||
dispatch(importFetchedAccount(parsedAccount));
|
||||
dispatch(importEntities({ accounts: [parsedAccount] }));
|
||||
dispatch({ type: VERIFY_CREDENTIALS_SUCCESS, token, account: parsedAccount });
|
||||
if (account.id === getState().me) dispatch(fetchMeSuccess(parsedAccount));
|
||||
return parsedAccount;
|
||||
|
@ -175,7 +175,7 @@ const rememberAuthAccount = (accountUrl: string) =>
|
|||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch({ type: AUTH_ACCOUNT_REMEMBER_REQUEST, accountUrl });
|
||||
return KVStore.getItemOrError(`authAccount:${accountUrl}`).then(account => {
|
||||
dispatch(importFetchedAccount(account));
|
||||
dispatch(importEntities({ accounts: [account] }));
|
||||
dispatch({ type: AUTH_ACCOUNT_REMEMBER_SUCCESS, account, accountUrl });
|
||||
if (account.id === getState().me) dispatch(fetchMeSuccess(account));
|
||||
return account;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { PaginatedResponse, Status } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -24,7 +24,7 @@ const fetchBookmarkedStatuses = (folderId?: string) =>
|
|||
dispatch(fetchBookmarkedStatusesRequest(folderId));
|
||||
|
||||
return getClient(getState()).myAccount.getBookmarks({ folder_id: folderId }).then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
return dispatch(fetchBookmarkedStatusesSuccess(response.items, response.next, folderId));
|
||||
}).catch(error => {
|
||||
dispatch(fetchBookmarkedStatusesFail(error, folderId));
|
||||
|
@ -61,7 +61,7 @@ const expandBookmarkedStatuses = (folderId?: string) =>
|
|||
dispatch(expandBookmarkedStatusesRequest(folderId));
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
return dispatch(expandBookmarkedStatusesSuccess(response.items, response.next, folderId));
|
||||
}).catch(error => {
|
||||
dispatch(expandBookmarkedStatusesFail(error, folderId));
|
||||
|
|
|
@ -14,7 +14,7 @@ import toast from 'pl-fe/toast';
|
|||
import { isLoggedIn } from 'pl-fe/utils/auth';
|
||||
|
||||
import { chooseEmoji } from './emojis';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
import { rememberLanguageUse } from './languages';
|
||||
import { uploadFile, updateMedia } from './media';
|
||||
import { createStatus } from './statuses';
|
||||
|
@ -357,12 +357,13 @@ interface SubmitComposeOpts {
|
|||
history?: History;
|
||||
force?: boolean;
|
||||
onSubmit?: () => void;
|
||||
onSuccess?: () => void;
|
||||
propagate?: boolean;
|
||||
}
|
||||
|
||||
const submitCompose = (composeId: string, opts: SubmitComposeOpts = {}) =>
|
||||
async (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const { history, force = false, onSubmit, propagate } = opts;
|
||||
const { history, force = false, onSubmit, onSuccess, propagate } = opts;
|
||||
|
||||
if (!isLoggedIn(getState)) return;
|
||||
const state = getState();
|
||||
|
@ -388,7 +389,7 @@ const submitCompose = (composeId: string, opts: SubmitComposeOpts = {}) =>
|
|||
useModalsStore.getState().openModal('MISSING_DESCRIPTION', {
|
||||
onContinue: () => {
|
||||
useModalsStore.getState().closeModal('MISSING_DESCRIPTION');
|
||||
dispatch(submitCompose(composeId, { history, force: true }));
|
||||
dispatch(submitCompose(composeId, { history, force: true, onSuccess }));
|
||||
},
|
||||
});
|
||||
return;
|
||||
|
@ -460,7 +461,8 @@ const submitCompose = (composeId: string, opts: SubmitComposeOpts = {}) =>
|
|||
history.push('/conversations');
|
||||
}
|
||||
handleComposeSubmit(dispatch, getState, composeId, data, status, !!statusId, propagate);
|
||||
if (onSubmit) onSubmit();
|
||||
onSubmit?.();
|
||||
onSuccess?.();
|
||||
}).catch((error) => {
|
||||
dispatch(submitComposeFail(composeId, error));
|
||||
});
|
||||
|
@ -610,7 +612,7 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, composeId,
|
|||
|
||||
return getClient(getState).accounts.searchAccounts(token.slice(1), { resolve: false, limit: 10 }, { signal })
|
||||
.then(response => {
|
||||
dispatch(importFetchedAccounts(response));
|
||||
dispatch(importEntities({ accounts: response }));
|
||||
dispatch(readyComposeSuggestionsAccounts(composeId, token, response));
|
||||
}).catch(error => {
|
||||
if (!signal.aborted) {
|
||||
|
|
|
@ -2,13 +2,9 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import {
|
||||
importFetchedAccounts,
|
||||
importFetchedStatuses,
|
||||
importFetchedStatus,
|
||||
} from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account, Conversation, PaginatedResponse, Status } from 'pl-api';
|
||||
import type { Account, Conversation, PaginatedResponse } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
const CONVERSATIONS_MOUNT = 'CONVERSATIONS_MOUNT' as const;
|
||||
|
@ -48,8 +44,10 @@ const expandConversations = (expand = true) => (dispatch: AppDispatch, getState:
|
|||
|
||||
return (state.conversations.next?.() || getClient(state).timelines.getConversations())
|
||||
.then(response => {
|
||||
dispatch(importFetchedAccounts(response.items.reduce((aggr: Array<Account>, item) => aggr.concat(item.accounts), [])));
|
||||
dispatch(importFetchedStatuses(response.items.map((item) => item.last_status).filter((x): x is Status => x !== null)));
|
||||
dispatch(importEntities({
|
||||
accounts: response.items.reduce((aggr: Array<Account>, item) => aggr.concat(item.accounts), []),
|
||||
statuses: response.items.map((item) => item.last_status),
|
||||
}));
|
||||
dispatch(expandConversationsSuccess(response.items, response.next, isLoadingRecent));
|
||||
})
|
||||
.catch(err => dispatch(expandConversationsFail(err)));
|
||||
|
@ -74,11 +72,10 @@ const expandConversationsFail = (error: unknown) => ({
|
|||
});
|
||||
|
||||
const updateConversations = (conversation: Conversation) => (dispatch: AppDispatch) => {
|
||||
dispatch(importFetchedAccounts(conversation.accounts));
|
||||
|
||||
if (conversation.last_status) {
|
||||
dispatch(importFetchedStatus(conversation.last_status));
|
||||
}
|
||||
dispatch(importEntities({
|
||||
accounts: conversation.accounts,
|
||||
statuses: [conversation.last_status],
|
||||
}));
|
||||
|
||||
return dispatch({
|
||||
type: CONVERSATIONS_UPDATE,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account, ProfileDirectoryParams } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -19,7 +19,7 @@ const fetchDirectory = (params: ProfileDirectoryParams) =>
|
|||
dispatch(fetchDirectoryRequest());
|
||||
|
||||
return getClient(getState()).instance.profileDirectory({ ...params, limit: 20 }).then((data) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
dispatch(importEntities({ accounts: data }));
|
||||
dispatch(fetchDirectorySuccess(data));
|
||||
dispatch(fetchRelationships(data.map((x) => x.id)));
|
||||
}).catch(error => dispatch(fetchDirectoryFail(error)));
|
||||
|
@ -46,7 +46,7 @@ const expandDirectory = (params: Record<string, any>) =>
|
|||
const loadedItems = getState().user_lists.directory.items.size;
|
||||
|
||||
return getClient(getState()).instance.profileDirectory({ ...params, offset: loadedItems, limit: 20 }).then((data) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
dispatch(importEntities({ accounts: data }));
|
||||
dispatch(expandDirectorySuccess(data));
|
||||
dispatch(fetchRelationships(data.map((x) => x.id)));
|
||||
}).catch(error => dispatch(expandDirectoryFail(error)));
|
||||
|
|
|
@ -2,7 +2,7 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatus } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Status } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -24,7 +24,7 @@ const emojiReact = (status: Pick<Status, 'id'>, emoji: string, custom?: string)
|
|||
dispatch(emojiReactRequest(status.id, emoji, custom));
|
||||
|
||||
return getClient(getState).statuses.createStatusReaction(status.id, emoji).then((response) => {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
dispatch(emojiReactSuccess(response, emoji));
|
||||
}).catch((error) => {
|
||||
dispatch(emojiReactFail(status.id, emoji, error));
|
||||
|
@ -38,7 +38,7 @@ const unEmojiReact = (status: Pick<Status, 'id'>, emoji: string) =>
|
|||
dispatch(unEmojiReactRequest(status.id, emoji));
|
||||
|
||||
return getClient(getState).statuses.deleteStatusReaction(status.id, emoji).then(response => {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
dispatch(unEmojiReactSuccess(response, emoji));
|
||||
}).catch(error => {
|
||||
dispatch(unEmojiReactFail(status.id, emoji, error));
|
||||
|
|
|
@ -4,7 +4,7 @@ import { getClient } from 'pl-fe/api';
|
|||
import { useModalsStore } from 'pl-fe/stores/modals';
|
||||
import toast from 'pl-fe/toast';
|
||||
|
||||
import { importFetchedAccounts, importFetchedStatus, importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
import { STATUS_FETCH_SOURCE_FAIL, STATUS_FETCH_SOURCE_REQUEST, STATUS_FETCH_SOURCE_SUCCESS } from './statuses';
|
||||
|
||||
import type { Account, CreateEventParams, Location, MediaAttachment, PaginatedResponse, Status } from 'pl-api';
|
||||
|
@ -132,7 +132,7 @@ const submitEvent = ({
|
|||
: getClient(state).events.editEvent(statusId, params)
|
||||
).then((data) => {
|
||||
useModalsStore.getState().closeModal('COMPOSE_EVENT');
|
||||
dispatch(importFetchedStatus(data));
|
||||
dispatch(importEntities({ statuses: [data] }));
|
||||
dispatch(submitEventSuccess(data));
|
||||
toast.success(
|
||||
statusId ? messages.editSuccess : messages.success,
|
||||
|
@ -171,7 +171,7 @@ const joinEvent = (statusId: string, participationMessage?: string) =>
|
|||
dispatch(joinEventRequest(status.id));
|
||||
|
||||
return getClient(getState).events.joinEvent(statusId, participationMessage).then((data) => {
|
||||
dispatch(importFetchedStatus(data));
|
||||
dispatch(importEntities({ statuses: [data] }));
|
||||
dispatch(joinEventSuccess(status.id));
|
||||
toast.success(
|
||||
data.event?.join_state === 'pending' ? messages.joinRequestSuccess : messages.joinSuccess,
|
||||
|
@ -213,7 +213,7 @@ const leaveEvent = (statusId: string) =>
|
|||
dispatch(leaveEventRequest(status.id));
|
||||
|
||||
return getClient(getState).events.leaveEvent(statusId).then((data) => {
|
||||
dispatch(importFetchedStatus(data));
|
||||
dispatch(importEntities({ statuses: [data] }));
|
||||
dispatch(leaveEventSuccess(status.id));
|
||||
}).catch((error) => {
|
||||
dispatch(leaveEventFail(error, status.id));
|
||||
|
@ -241,7 +241,7 @@ const fetchEventParticipations = (statusId: string) =>
|
|||
dispatch(fetchEventParticipationsRequest(statusId));
|
||||
|
||||
return getClient(getState).events.getEventParticipations(statusId).then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
return dispatch(fetchEventParticipationsSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(fetchEventParticipationsFail(statusId, error));
|
||||
|
@ -277,7 +277,7 @@ const expandEventParticipations = (statusId: string) =>
|
|||
dispatch(expandEventParticipationsRequest(statusId));
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
return dispatch(expandEventParticipationsSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(expandEventParticipationsFail(statusId, error));
|
||||
|
@ -307,7 +307,7 @@ const fetchEventParticipationRequests = (statusId: string) =>
|
|||
dispatch(fetchEventParticipationRequestsRequest(statusId));
|
||||
|
||||
return getClient(getState).events.getEventParticipationRequests(statusId).then(response => {
|
||||
dispatch(importFetchedAccounts(response.items.map(({ account }) => account)));
|
||||
dispatch(importEntities({ accounts: response.items.map(({ account }) => account) }));
|
||||
return dispatch(fetchEventParticipationRequestsSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(fetchEventParticipationRequestsFail(statusId, error));
|
||||
|
@ -346,7 +346,7 @@ const expandEventParticipationRequests = (statusId: string) =>
|
|||
dispatch(expandEventParticipationRequestsRequest(statusId));
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedAccounts(response.items.map(({ account }) => account)));
|
||||
dispatch(importEntities({ accounts: response.items.map(({ account }) => account) }));
|
||||
return dispatch(expandEventParticipationRequestsSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(expandEventParticipationRequestsFail(statusId, error));
|
||||
|
@ -479,7 +479,7 @@ const fetchRecentEvents = () =>
|
|||
return getClient(getState()).timelines.publicTimeline({
|
||||
only_events: true,
|
||||
}).then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch({
|
||||
type: RECENT_EVENTS_FETCH_SUCCESS,
|
||||
statuses: response.items,
|
||||
|
@ -499,7 +499,7 @@ const fetchJoinedEvents = () =>
|
|||
dispatch({ type: JOINED_EVENTS_FETCH_REQUEST });
|
||||
|
||||
getClient(getState).events.getJoinedEvents().then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch({
|
||||
type: JOINED_EVENTS_FETCH_SUCCESS,
|
||||
statuses: response.items,
|
||||
|
|
|
@ -3,7 +3,7 @@ import { AppDispatch, RootState } from 'pl-fe/store';
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
const FAMILIAR_FOLLOWERS_FETCH_REQUEST = 'FAMILIAR_FOLLOWERS_FETCH_REQUEST' as const;
|
||||
const FAMILIAR_FOLLOWERS_FETCH_SUCCESS = 'FAMILIAR_FOLLOWERS_FETCH_SUCCESS' as const;
|
||||
|
@ -19,7 +19,7 @@ const fetchAccountFamiliarFollowers = (accountId: string) => (dispatch: AppDispa
|
|||
.then((data) => {
|
||||
const accounts = data.find(({ id }: { id: string }) => id === accountId)!.accounts;
|
||||
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importEntities({ accounts }));
|
||||
dispatch(fetchRelationships(accounts.map((item) => item.id)));
|
||||
dispatch({
|
||||
type: FAMILIAR_FOLLOWERS_FETCH_SUCCESS,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { PaginatedResponse, Status } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -34,7 +34,7 @@ const fetchFavouritedStatuses = () =>
|
|||
dispatch(fetchFavouritedStatusesRequest());
|
||||
|
||||
return getClient(getState()).myAccount.getFavourites().then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch(fetchFavouritedStatusesSuccess(response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(fetchFavouritedStatusesFail(error));
|
||||
|
@ -69,7 +69,7 @@ const expandFavouritedStatuses = () =>
|
|||
dispatch(expandFavouritedStatusesRequest());
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch(expandFavouritedStatusesSuccess(response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(expandFavouritedStatusesFail(error));
|
||||
|
@ -102,7 +102,7 @@ const fetchAccountFavouritedStatuses = (accountId: string) =>
|
|||
dispatch(fetchAccountFavouritedStatusesRequest(accountId));
|
||||
|
||||
return getClient(getState).accounts.getAccountFavourites(accountId).then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch(fetchAccountFavouritedStatusesSuccess(accountId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(fetchAccountFavouritedStatusesFail(accountId, error));
|
||||
|
@ -140,7 +140,7 @@ const expandAccountFavouritedStatuses = (accountId: string) =>
|
|||
dispatch(expandAccountFavouritedStatusesRequest(accountId));
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch(expandAccountFavouritedStatusesSuccess(accountId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(expandAccountFavouritedStatusesFail(accountId, error));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account, PaginatedResponse } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -23,7 +23,7 @@ const fetchGroupBlocks = (groupId: string) =>
|
|||
dispatch(fetchGroupBlocksRequest(groupId));
|
||||
|
||||
return getClient(getState).experimental.groups.getGroupBlocks(groupId).then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(fetchGroupBlocksSuccess(groupId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
dispatch(fetchGroupBlocksFail(groupId, error));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getClient } from 'pl-fe/api';
|
||||
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { StatusEdit } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -18,7 +18,7 @@ const fetchHistory = (statusId: string) =>
|
|||
dispatch(fetchHistoryRequest(statusId));
|
||||
|
||||
return getClient(getState()).statuses.getStatusHistory(statusId).then(data => {
|
||||
dispatch(importFetchedAccounts(data.map((x) => x.account)));
|
||||
dispatch(importEntities({ accounts: data.map((x) => x.account) }));
|
||||
dispatch(fetchHistorySuccess(statusId, data));
|
||||
}).catch(error => dispatch(fetchHistoryFail(statusId, error)));
|
||||
};
|
||||
|
|
121
packages/pl-fe/src/actions/importer.ts
Normal file
121
packages/pl-fe/src/actions/importer.ts
Normal file
|
@ -0,0 +1,121 @@
|
|||
import { importEntities as importEntityStoreEntities } from 'pl-fe/entity-store/actions';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
import { normalizeGroup } from 'pl-fe/normalizers/group';
|
||||
|
||||
import type { Account as BaseAccount, Group as BaseGroup, Poll as BasePoll, Relationship as BaseRelationship, Status as BaseStatus } from 'pl-api';
|
||||
import type { AppDispatch } from 'pl-fe/store';
|
||||
|
||||
const STATUS_IMPORT = 'STATUS_IMPORT' as const;
|
||||
const STATUSES_IMPORT = 'STATUSES_IMPORT' as const;
|
||||
const POLLS_IMPORT = 'POLLS_IMPORT' as const;
|
||||
|
||||
// Sometimes Pleroma can return an empty account,
|
||||
// or a repost can appear of a deleted account. Skip these statuses.
|
||||
const isBroken = (status: BaseStatus) => {
|
||||
try {
|
||||
if (status.scheduled_at !== null) return true;
|
||||
// Skip empty accounts
|
||||
// https://gitlab.com/soapbox-pub/soapbox/-/issues/424
|
||||
if (!status.account.id) return true;
|
||||
// Skip broken reposts
|
||||
// https://gitlab.com/soapbox-pub/rebased/-/issues/28
|
||||
if (status.reblog && !status.reblog.account.id) return true;
|
||||
return false;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const isEmpty = (object: Record<string, any>) => !Object.values(object).some(value => value);
|
||||
|
||||
interface ImportStatusAction {
|
||||
type: typeof STATUS_IMPORT;
|
||||
status: BaseStatus;
|
||||
idempotencyKey?: string;
|
||||
}
|
||||
|
||||
interface ImportStatusesAction {
|
||||
type: typeof STATUSES_IMPORT;
|
||||
statuses: Array<BaseStatus>;
|
||||
}
|
||||
|
||||
interface ImportPollAction {
|
||||
type: typeof POLLS_IMPORT;
|
||||
polls: Array<BasePoll>;
|
||||
}
|
||||
|
||||
const importEntities = (entities: {
|
||||
accounts?: Array<BaseAccount | undefined | null>;
|
||||
groups?: Array<BaseGroup | undefined | null>;
|
||||
polls?: Array<BasePoll | undefined | null>;
|
||||
statuses?: Array<BaseStatus & { expectsCard?: boolean } | undefined | null>;
|
||||
relationships?: Array<BaseRelationship | undefined | null>;
|
||||
}, options: {
|
||||
withParents?: boolean;
|
||||
idempotencyKey?: string;
|
||||
} = {
|
||||
withParents: true,
|
||||
}) => (dispatch: AppDispatch) => {
|
||||
const accounts: Record<string, BaseAccount> = {};
|
||||
const groups: Record<string, BaseGroup> = {};
|
||||
const polls: Record<string, BasePoll> = {};
|
||||
const relationships: Record<string, BaseRelationship> = {};
|
||||
const statuses: Record<string, BaseStatus> = {};
|
||||
|
||||
const processAccount = (account: BaseAccount, withSelf = true) => {
|
||||
if (withSelf) accounts[account.id] = account;
|
||||
|
||||
if (account.moved) processAccount(account.moved);
|
||||
if (account.relationship) relationships[account.relationship.id] = account.relationship;
|
||||
};
|
||||
|
||||
const processStatus = (status: BaseStatus, withSelf = true) => {
|
||||
// Skip broken statuses
|
||||
if (isBroken(status)) return;
|
||||
|
||||
if (withSelf) statuses[status.id] = status;
|
||||
|
||||
if (status.account) {
|
||||
processAccount(status.account);
|
||||
}
|
||||
|
||||
if (status.quote) processStatus(status.quote);
|
||||
if (status.reblog) processStatus(status.reblog);
|
||||
if (status.poll) polls[status.poll.id] = status.poll;
|
||||
if (status.group) groups[status.group.id] = status.group;
|
||||
};
|
||||
|
||||
if (options.withParents) {
|
||||
entities.groups?.forEach(group => group && (groups[group.id] = group));
|
||||
entities.polls?.forEach(poll => poll && (polls[poll.id] = poll));
|
||||
entities.relationships?.forEach(relationship => relationship && (relationships[relationship.id] = relationship));
|
||||
}
|
||||
|
||||
entities.accounts?.forEach((account) => account && processAccount(account, options.withParents));
|
||||
|
||||
if (entities.statuses?.length === 1 && entities.statuses[0] && options.idempotencyKey) {
|
||||
dispatch<ImportStatusAction>({
|
||||
type: STATUS_IMPORT,
|
||||
status: entities.statuses[0], idempotencyKey: options.idempotencyKey,
|
||||
});
|
||||
processStatus(entities.statuses[0], false);
|
||||
} else {
|
||||
entities.statuses?.forEach((status) => status && processStatus(status, options.withParents));
|
||||
}
|
||||
|
||||
if (!isEmpty(accounts)) dispatch(importEntityStoreEntities(Object.values(accounts), Entities.ACCOUNTS));
|
||||
if (!isEmpty(groups)) dispatch(importEntityStoreEntities(Object.values(groups).map(normalizeGroup), Entities.GROUPS));
|
||||
if (!isEmpty(polls)) dispatch<ImportPollAction>(({ type: POLLS_IMPORT, polls: Object.values(polls) }));
|
||||
if (!isEmpty(relationships)) dispatch(importEntityStoreEntities(Object.values(relationships), Entities.RELATIONSHIPS));
|
||||
if (!isEmpty(statuses)) dispatch<ImportStatusesAction>({ type: STATUSES_IMPORT, statuses: Object.values(statuses) });
|
||||
};
|
||||
|
||||
type ImporterAction = ImportStatusAction | ImportStatusesAction | ImportPollAction;
|
||||
|
||||
export {
|
||||
STATUS_IMPORT,
|
||||
STATUSES_IMPORT,
|
||||
POLLS_IMPORT,
|
||||
importEntities,
|
||||
type ImporterAction,
|
||||
};
|
|
@ -1,169 +0,0 @@
|
|||
import { importEntities } from 'pl-fe/entity-store/actions';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
import { normalizeAccount } from 'pl-fe/normalizers/account';
|
||||
import { normalizeGroup } from 'pl-fe/normalizers/group';
|
||||
|
||||
import type { Account as BaseAccount, Group, Poll, Status as BaseStatus } from 'pl-api';
|
||||
import type { AppDispatch } from 'pl-fe/store';
|
||||
|
||||
const STATUS_IMPORT = 'STATUS_IMPORT' as const;
|
||||
const STATUSES_IMPORT = 'STATUSES_IMPORT' as const;
|
||||
const POLLS_IMPORT = 'POLLS_IMPORT' as const;
|
||||
|
||||
const importAccounts = (data: Array<BaseAccount>) => (dispatch: AppDispatch) => {
|
||||
try {
|
||||
const accounts = data.map(normalizeAccount);
|
||||
const relationships = accounts.map(account => account.relationship).filter(relationship => !!relationship);
|
||||
|
||||
dispatch(importEntities(accounts, Entities.ACCOUNTS));
|
||||
dispatch(importEntities(relationships, Entities.RELATIONSHIPS));
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
};
|
||||
|
||||
const importGroup = (data: Group) => importGroups([data]);
|
||||
|
||||
const importGroups = (data: Array<Group>) => (dispatch: AppDispatch) => {
|
||||
try {
|
||||
const groups = data.map(normalizeGroup);
|
||||
dispatch(importEntities(groups, Entities.GROUPS));
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
};
|
||||
|
||||
const importStatus = (status: BaseStatus & { expectsCard?: boolean }, idempotencyKey?: string) => ({ type: STATUS_IMPORT, status, idempotencyKey });
|
||||
|
||||
const importStatuses = (statuses: Array<BaseStatus>) => ({ type: STATUSES_IMPORT, statuses });
|
||||
|
||||
const importPolls = (polls: Array<Poll>) => ({ type: POLLS_IMPORT, polls });
|
||||
|
||||
const importFetchedAccount = (account: BaseAccount) =>
|
||||
importFetchedAccounts([account]);
|
||||
|
||||
const importFetchedAccounts = (accounts: Array<BaseAccount>) => {
|
||||
const normalAccounts: Array<BaseAccount> = [];
|
||||
|
||||
const processAccount = (account: BaseAccount) => {
|
||||
if (!account.id) return;
|
||||
|
||||
normalAccounts.push(account);
|
||||
|
||||
if (account.moved) {
|
||||
processAccount(account.moved);
|
||||
}
|
||||
};
|
||||
|
||||
accounts.forEach(processAccount);
|
||||
|
||||
return importAccounts(normalAccounts);
|
||||
};
|
||||
|
||||
const importFetchedStatus = (status: BaseStatus & { expectsCard?: boolean }, idempotencyKey?: string) =>
|
||||
(dispatch: AppDispatch) => {
|
||||
// Skip broken statuses
|
||||
if (isBroken(status)) return;
|
||||
|
||||
if (status.reblog?.id) {
|
||||
dispatch(importFetchedStatus(status.reblog as BaseStatus));
|
||||
}
|
||||
|
||||
// Fedibird quotes
|
||||
if (status.quote?.id) {
|
||||
dispatch(importFetchedStatus(status.quote as BaseStatus));
|
||||
}
|
||||
|
||||
// Fedibird quote from reblog
|
||||
if (status.reblog?.quote?.id) {
|
||||
dispatch(importFetchedStatus(status.reblog.quote));
|
||||
}
|
||||
|
||||
if (status.poll?.id) {
|
||||
dispatch(importFetchedPoll(status.poll));
|
||||
}
|
||||
|
||||
if (status.group?.id) {
|
||||
dispatch(importGroup(status.group));
|
||||
}
|
||||
|
||||
dispatch(importFetchedAccount(status.account));
|
||||
dispatch(importStatus(status, idempotencyKey));
|
||||
};
|
||||
|
||||
// Sometimes Pleroma can return an empty account,
|
||||
// or a repost can appear of a deleted account. Skip these statuses.
|
||||
const isBroken = (status: BaseStatus) => {
|
||||
try {
|
||||
if (status.scheduled_at !== null) return true;
|
||||
// Skip empty accounts
|
||||
// https://gitlab.com/soapbox-pub/soapbox/-/issues/424
|
||||
if (!status.account.id) return true;
|
||||
// Skip broken reposts
|
||||
// https://gitlab.com/soapbox-pub/rebased/-/issues/28
|
||||
if (status.reblog && !status.reblog.account.id) return true;
|
||||
return false;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const importFetchedStatuses = (statuses: Array<Omit<BaseStatus, 'account'> & { account: BaseAccount | null }>) => (dispatch: AppDispatch) => {
|
||||
const accounts: Record<string, BaseAccount> = {};
|
||||
const normalStatuses: Array<BaseStatus> = [];
|
||||
const polls: Array<Poll> = [];
|
||||
|
||||
const processStatus = (status: BaseStatus) => {
|
||||
if (status.account === null) return;
|
||||
// Skip broken statuses
|
||||
if (isBroken(status)) return;
|
||||
|
||||
normalStatuses.push(status);
|
||||
|
||||
accounts[status.account.id] = status.account;
|
||||
// if (status.accounts) {
|
||||
// accounts.push(...status.accounts);
|
||||
// }
|
||||
|
||||
if (status.reblog?.id) {
|
||||
processStatus(status.reblog as BaseStatus);
|
||||
}
|
||||
|
||||
// Fedibird quotes
|
||||
if (status.quote?.id) {
|
||||
processStatus(status.quote as BaseStatus);
|
||||
}
|
||||
|
||||
if (status.poll?.id) {
|
||||
polls.push(status.poll);
|
||||
}
|
||||
};
|
||||
|
||||
(statuses as Array<BaseStatus>).forEach(processStatus);
|
||||
|
||||
dispatch(importPolls(polls));
|
||||
dispatch(importFetchedAccounts(Object.values(accounts)));
|
||||
dispatch(importStatuses(normalStatuses));
|
||||
};
|
||||
|
||||
const importFetchedPoll = (poll: Poll) =>
|
||||
(dispatch: AppDispatch) => {
|
||||
dispatch(importPolls([poll]));
|
||||
};
|
||||
|
||||
type ImporterAction =
|
||||
| ReturnType<typeof importStatus>
|
||||
| ReturnType<typeof importStatuses>
|
||||
| ReturnType<typeof importPolls>;
|
||||
|
||||
export {
|
||||
STATUS_IMPORT,
|
||||
STATUSES_IMPORT,
|
||||
POLLS_IMPORT,
|
||||
importFetchedAccount,
|
||||
importFetchedAccounts,
|
||||
importFetchedStatus,
|
||||
importFetchedStatuses,
|
||||
importFetchedPoll,
|
||||
type ImporterAction,
|
||||
};
|
|
@ -7,7 +7,7 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importFetchedAccounts, importFetchedStatus } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account, EmojiReaction, PaginatedResponse, Status } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -97,7 +97,7 @@ const reblog = (status: Pick<Status, 'id'>) =>
|
|||
return getClient(getState()).statuses.reblogStatus(status.id).then((response) => {
|
||||
// The reblog API method returns a new status wrapped around the original. In this case we are only
|
||||
// interested in how the original is modified, hence passing it skipping the wrapper
|
||||
if (response.reblog) dispatch(importFetchedStatus(response.reblog as Status));
|
||||
if (response.reblog) dispatch(importEntities({ statuses: [response.reblog] }));
|
||||
dispatch(reblogSuccess(response));
|
||||
}).catch(error => {
|
||||
dispatch(reblogFail(status.id, error));
|
||||
|
@ -307,7 +307,7 @@ const bookmark = (status: Pick<Status, 'id'>, folderId?: string) =>
|
|||
dispatch(bookmarkRequest(status.id));
|
||||
|
||||
return getClient(getState()).statuses.bookmarkStatus(status.id, folderId).then((response) => {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
dispatch(bookmarkSuccess(response));
|
||||
|
||||
let opts: IToastOptions = {
|
||||
|
@ -335,7 +335,7 @@ const unbookmark = (status: Pick<Status, 'id'>) =>
|
|||
dispatch(unbookmarkRequest(status.id));
|
||||
|
||||
return getClient(getState()).statuses.unbookmarkStatus(status.id).then(response => {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
dispatch(unbookmarkSuccess(response));
|
||||
toast.success(messages.bookmarkRemoved);
|
||||
}).catch(error => {
|
||||
|
@ -391,7 +391,7 @@ const fetchReblogs = (statusId: string) =>
|
|||
dispatch(fetchReblogsRequest(statusId));
|
||||
|
||||
return getClient(getState()).statuses.getRebloggedBy(statusId).then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(fetchRelationships(response.items.map((item) => item.id)));
|
||||
dispatch(fetchReblogsSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
|
@ -420,7 +420,7 @@ const fetchReblogsFail = (statusId: string, error: unknown) => ({
|
|||
const expandReblogs = (statusId: string, next: AccountListLink) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
next().then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(fetchRelationships(response.items.map((item) => item.id)));
|
||||
dispatch(expandReblogsSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
|
@ -446,7 +446,7 @@ const fetchFavourites = (statusId: string) =>
|
|||
dispatch(fetchFavouritesRequest(statusId));
|
||||
|
||||
return getClient(getState()).statuses.getFavouritedBy(statusId).then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(fetchRelationships(response.items.map((item) => item.id)));
|
||||
dispatch(fetchFavouritesSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
|
@ -475,7 +475,7 @@ const fetchFavouritesFail = (statusId: string, error: unknown) => ({
|
|||
const expandFavourites = (statusId: string, next: AccountListLink) =>
|
||||
(dispatch: AppDispatch) => {
|
||||
next().then(response => {
|
||||
dispatch(importFetchedAccounts(response.items));
|
||||
dispatch(importEntities({ accounts: response.items }));
|
||||
dispatch(fetchRelationships(response.items.map((item) => item.id)));
|
||||
dispatch(expandFavouritesSuccess(statusId, response.items, response.next));
|
||||
}).catch(error => {
|
||||
|
@ -501,7 +501,7 @@ const fetchDislikes = (statusId: string) =>
|
|||
dispatch(fetchDislikesRequest(statusId));
|
||||
|
||||
return getClient(getState).statuses.getDislikedBy(statusId).then(response => {
|
||||
dispatch(importFetchedAccounts(response));
|
||||
dispatch(importEntities({ accounts: response }));
|
||||
dispatch(fetchRelationships(response.map((item) => item.id)));
|
||||
dispatch(fetchDislikesSuccess(statusId, response));
|
||||
}).catch(error => {
|
||||
|
@ -531,7 +531,7 @@ const fetchReactions = (statusId: string) =>
|
|||
dispatch(fetchReactionsRequest(statusId));
|
||||
|
||||
return getClient(getState).statuses.getStatusReactions(statusId).then(response => {
|
||||
dispatch(importFetchedAccounts((response).map(({ accounts }) => accounts).flat()));
|
||||
dispatch(importEntities({ accounts: (response).map(({ accounts }) => accounts).flat() }));
|
||||
dispatch(fetchReactionsSuccess(statusId, response));
|
||||
}).catch(error => {
|
||||
dispatch(fetchReactionsFail(statusId, error));
|
||||
|
@ -562,7 +562,7 @@ const pin = (status: Pick<Status, 'id'>, accountId: string) =>
|
|||
dispatch(pinRequest(status.id, accountId));
|
||||
|
||||
return getClient(getState()).statuses.pinStatus(status.id).then(response => {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
dispatch(pinSuccess(response, accountId));
|
||||
}).catch(error => {
|
||||
dispatch(pinFail(status.id, error, accountId));
|
||||
|
@ -596,7 +596,7 @@ const unpin = (status: Pick<Status, 'id'>, accountId: string) =>
|
|||
dispatch(unpinRequest(status.id, accountId));
|
||||
|
||||
return getClient(getState()).statuses.unpinStatus(status.id).then(response => {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
dispatch(unpinSuccess(response, accountId));
|
||||
}).catch(error => {
|
||||
dispatch(unpinFail(status.id, error, accountId));
|
||||
|
|
|
@ -4,7 +4,7 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account, List, PaginatedResponse } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -229,7 +229,7 @@ const fetchListAccounts = (listId: string) => (dispatch: AppDispatch, getState:
|
|||
dispatch(fetchListAccountsRequest(listId));
|
||||
|
||||
return getClient(getState()).lists.getListAccounts(listId).then(({ items, next }) => {
|
||||
dispatch(importFetchedAccounts(items));
|
||||
dispatch(importEntities({ accounts: items }));
|
||||
dispatch(fetchListAccountsSuccess(listId, items, next));
|
||||
}).catch(err => dispatch(fetchListAccountsFail(listId, err)));
|
||||
};
|
||||
|
@ -256,7 +256,7 @@ const fetchListSuggestions = (q: string) => (dispatch: AppDispatch, getState: ()
|
|||
if (!isLoggedIn(getState)) return;
|
||||
|
||||
return getClient(getState()).accounts.searchAccounts(q, { resolve: false, limit: 4, following: true }).then((data) => {
|
||||
dispatch(importFetchedAccounts(data));
|
||||
dispatch(importEntities({ accounts: data }));
|
||||
dispatch(fetchListSuggestionsReady(q, data));
|
||||
}).catch(error => toast.showAlertForError(error));
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ import { getAuthUserId, getAuthUserUrl } from 'pl-fe/utils/auth';
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { loadCredentials } from './auth';
|
||||
import { importFetchedAccount } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
import { FE_NAME } from './settings';
|
||||
|
||||
import type { CredentialAccount, UpdateCredentialsParams } from 'pl-api';
|
||||
|
@ -127,7 +127,7 @@ const patchMeSuccess = (me: CredentialAccount) =>
|
|||
me,
|
||||
};
|
||||
|
||||
dispatch(importFetchedAccount(me));
|
||||
dispatch(importEntities({ accounts: [me] }));
|
||||
dispatch(action);
|
||||
};
|
||||
|
||||
|
|
|
@ -14,12 +14,7 @@ import { EXCLUDE_TYPES, NOTIFICATION_TYPES } from 'pl-fe/utils/notification';
|
|||
import { joinPublicPath } from 'pl-fe/utils/static';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import {
|
||||
importFetchedAccount,
|
||||
importFetchedAccounts,
|
||||
importFetchedStatus,
|
||||
importFetchedStatuses,
|
||||
} from './importer';
|
||||
import { importEntities } from './importer';
|
||||
import { saveMarker } from './markers';
|
||||
import { saveSettings } from './settings';
|
||||
|
||||
|
@ -76,20 +71,10 @@ const updateNotifications = (notification: BaseNotification) =>
|
|||
const selectedFilter = useSettingsStore.getState().settings.notifications.quickFilter.active;
|
||||
const showInColumn = selectedFilter === 'all' ? true : (FILTER_TYPES[selectedFilter as FilterType] || [notification.type]).includes(notification.type);
|
||||
|
||||
if (notification.account) {
|
||||
dispatch(importFetchedAccount(notification.account));
|
||||
}
|
||||
|
||||
// Used by Move notification
|
||||
if (notification.type === 'move' && notification.target) {
|
||||
dispatch(importFetchedAccount(notification.target));
|
||||
}
|
||||
|
||||
const status = getNotificationStatus(notification);
|
||||
|
||||
if (status) {
|
||||
dispatch(importFetchedStatus(status));
|
||||
}
|
||||
dispatch(importEntities({
|
||||
accounts: [notification.account, notification.type === 'move' ? notification.target : undefined],
|
||||
statuses: [getNotificationStatus(notification)],
|
||||
}));
|
||||
|
||||
if (showInColumn) {
|
||||
dispatch({
|
||||
|
@ -256,8 +241,10 @@ const expandNotifications = ({ maxId }: Record<string, any> = {}, done: () => an
|
|||
return acc;
|
||||
}, { accounts: {}, statuses: {} } as { accounts: Record<string, Account>; statuses: Record<string, Status> });
|
||||
|
||||
dispatch(importFetchedAccounts(Object.values(entries.accounts)));
|
||||
dispatch(importFetchedStatuses(Object.values(entries.statuses)));
|
||||
dispatch(importEntities({
|
||||
accounts: Object.values(entries.accounts),
|
||||
statuses: Object.values(entries.statuses),
|
||||
}));
|
||||
|
||||
const deduplicatedNotifications = normalizeNotifications(response.items, state.notifications.items);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { isLoggedIn } from 'pl-fe/utils/auth';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Status } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -19,7 +19,7 @@ const fetchPinnedStatuses = () =>
|
|||
dispatch(fetchPinnedStatusesRequest());
|
||||
|
||||
return getClient(getState()).accounts.getAccountStatuses(me as string, { pinned: true }).then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
dispatch(fetchPinnedStatusesSuccess(response.items, null));
|
||||
}).catch(error => {
|
||||
dispatch(fetchPinnedStatusesFail(error));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedPoll } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Poll } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -18,7 +18,7 @@ const vote = (pollId: string, choices: number[]) =>
|
|||
dispatch(voteRequest());
|
||||
|
||||
return getClient(getState()).polls.vote(pollId, choices).then((data) => {
|
||||
dispatch(importFetchedPoll(data));
|
||||
dispatch(importEntities({ polls: [data] }));
|
||||
dispatch(voteSuccess(data));
|
||||
}).catch(err => dispatch(voteFail(err)));
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ const fetchPoll = (pollId: string) =>
|
|||
dispatch(fetchPollRequest());
|
||||
|
||||
return getClient(getState()).polls.getPoll(pollId).then((data) => {
|
||||
dispatch(importFetchedPoll(data));
|
||||
dispatch(importEntities({ polls: [data] }));
|
||||
dispatch(fetchPollSuccess(data));
|
||||
}).catch(err => dispatch(fetchPollFail(err)));
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import mapValues from 'lodash/mapValues';
|
||||
|
||||
import { verifyCredentials } from './auth';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { AppDispatch } from 'pl-fe/store';
|
||||
|
||||
|
@ -54,7 +54,7 @@ const preloadMastodon = (data: Record<string, any>) =>
|
|||
const { me, access_token } = data.meta;
|
||||
const { url } = data.accounts[me];
|
||||
|
||||
dispatch(importFetchedAccounts(Object.values(data.accounts)));
|
||||
dispatch(importEntities({ accounts: Object.values(data.accounts) }));
|
||||
dispatch(verifyCredentials(access_token, url));
|
||||
dispatch({ type: MASTODON_PRELOAD_IMPORT, data });
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useSettingsStore } from 'pl-fe/stores/settings';
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importFetchedAccounts, importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Search } from 'pl-api';
|
||||
import type { SearchFilter } from 'pl-fe/reducers/search';
|
||||
|
@ -54,13 +54,7 @@ const submitSearch = (value: string, filter?: SearchFilter) =>
|
|||
if (accountId) params.account_id = accountId;
|
||||
|
||||
return getClient(getState()).search.search(value, params).then(response => {
|
||||
if (response.accounts) {
|
||||
dispatch(importFetchedAccounts(response.accounts));
|
||||
}
|
||||
|
||||
if (response.statuses) {
|
||||
dispatch(importFetchedStatuses(response.statuses));
|
||||
}
|
||||
dispatch(importEntities({ accounts: response.accounts, statuses: response.statuses }));
|
||||
|
||||
dispatch(fetchSearchSuccess(response, value, type));
|
||||
dispatch(fetchRelationships(response.accounts.map((item) => item.id)));
|
||||
|
@ -113,13 +107,7 @@ const expandSearch = (type: SearchFilter) => (dispatch: AppDispatch, getState: (
|
|||
if (accountId) params.account_id = accountId;
|
||||
|
||||
return getClient(getState()).search.search(value, params).then(response => {
|
||||
if (response.accounts) {
|
||||
dispatch(importFetchedAccounts(response.accounts));
|
||||
}
|
||||
|
||||
if (response.statuses) {
|
||||
dispatch(importFetchedStatuses(response.statuses));
|
||||
}
|
||||
dispatch(importEntities({ accounts: response.accounts, statuses: response.statuses }));
|
||||
|
||||
dispatch(expandSearchSuccess(response, value, type));
|
||||
dispatch(fetchRelationships(response.accounts.map((item) => item.id)));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Status as BaseStatus, PaginatedResponse } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -43,7 +43,7 @@ const fetchStatusQuotes = (statusId: string) =>
|
|||
dispatch(action);
|
||||
|
||||
return getClient(getState).statuses.getStatusQuotes(statusId).then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
const action: FetchStatusQuotesSuccessAction = {
|
||||
type: STATUS_QUOTES_FETCH_SUCCESS,
|
||||
statusId,
|
||||
|
@ -94,7 +94,7 @@ const expandStatusQuotes = (statusId: string) =>
|
|||
dispatch(action);
|
||||
|
||||
return next().then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
const action: ExpandStatusQuotesSuccessAction = {
|
||||
type: STATUS_QUOTES_EXPAND_SUCCESS,
|
||||
statusId,
|
||||
|
|
|
@ -6,7 +6,7 @@ import { shouldHaveCard } from 'pl-fe/utils/status';
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { setComposeToStatus } from './compose';
|
||||
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
import { deleteFromTimelines } from './timelines';
|
||||
|
||||
import type { CreateStatusParams, Status as BaseStatus } from 'pl-api';
|
||||
|
@ -66,7 +66,7 @@ const createStatus = (params: CreateStatusParams, idempotencyKey: string, status
|
|||
// The backend might still be processing the rich media attachment
|
||||
const expectsCard = status.scheduled_at === null && !status.card && shouldHaveCard(status);
|
||||
|
||||
if (status.scheduled_at === null) dispatch(importFetchedStatus({ ...status, expectsCard }, idempotencyKey));
|
||||
if (status.scheduled_at === null) dispatch(importEntities({ statuses: [{ ...status, expectsCard }] }, { idempotencyKey, withParents: true }));
|
||||
dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey, editing: !!statusId });
|
||||
|
||||
// Poll the backend for the updated card
|
||||
|
@ -76,7 +76,7 @@ const createStatus = (params: CreateStatusParams, idempotencyKey: string, status
|
|||
const poll = (retries = 5) => {
|
||||
return getClient(getState()).statuses.getStatus(status.id).then(response => {
|
||||
if (response.card) {
|
||||
dispatch(importFetchedStatus(response));
|
||||
dispatch(importEntities({ statuses: [response] }));
|
||||
} else if (retries > 0 && response) {
|
||||
setTimeout(() => poll(retries - 1), delay);
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ const fetchStatus = (statusId: string, intl?: IntlShape) =>
|
|||
} : undefined;
|
||||
|
||||
return getClient(getState()).statuses.getStatus(statusId, params).then(status => {
|
||||
dispatch(importFetchedStatus(status));
|
||||
dispatch(importEntities({ statuses: [status] }));
|
||||
dispatch({ type: STATUS_FETCH_SUCCESS, status });
|
||||
return status;
|
||||
}).catch(error => {
|
||||
|
@ -153,7 +153,7 @@ const deleteStatus = (statusId: string, withRedraft = false) =>
|
|||
};
|
||||
|
||||
const updateStatus = (status: BaseStatus) => (dispatch: AppDispatch) =>
|
||||
dispatch(importFetchedStatus(status));
|
||||
dispatch(importEntities({ statuses: [status] }));
|
||||
|
||||
const fetchContext = (statusId: string, intl?: IntlShape) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
|
@ -164,14 +164,10 @@ const fetchContext = (statusId: string, intl?: IntlShape) =>
|
|||
} : undefined;
|
||||
|
||||
return getClient(getState()).statuses.getContext(statusId, params).then(context => {
|
||||
if (typeof context === 'object') {
|
||||
const { ancestors, descendants } = context;
|
||||
const statuses = ancestors.concat(descendants);
|
||||
dispatch(importFetchedStatuses(statuses));
|
||||
dispatch({ type: CONTEXT_FETCH_SUCCESS, statusId, ancestors, descendants });
|
||||
} else {
|
||||
throw context;
|
||||
}
|
||||
const { ancestors, descendants } = context;
|
||||
const statuses = ancestors.concat(descendants);
|
||||
dispatch(importEntities({ statuses }));
|
||||
dispatch({ type: CONTEXT_FETCH_SUCCESS, statusId, ancestors, descendants });
|
||||
return context;
|
||||
}).catch(error => {
|
||||
if (error.response?.status === 404) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
import { insertSuggestionsIntoTimeline } from './timelines';
|
||||
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -24,7 +24,7 @@ const fetchSuggestions = (limit = 50) =>
|
|||
return getClient(getState).myAccount.getSuggestions(limit).then((suggestions) => {
|
||||
const accounts = suggestions.map(({ account }) => account);
|
||||
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importEntities({ accounts }));
|
||||
dispatch({ type: SUGGESTIONS_FETCH_SUCCESS, suggestions });
|
||||
|
||||
dispatch(fetchRelationships(accounts.map(({ id }) => id)));
|
||||
|
|
|
@ -6,7 +6,7 @@ import { shouldFilter } from 'pl-fe/utils/timelines';
|
|||
|
||||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { PaginatedResponse, Status as BaseStatus, PublicTimelineParams, HomeTimelineParams, ListTimelineParams, HashtagTimelineParams, GetAccountStatusesParams, GroupTimelineParams } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
@ -46,7 +46,7 @@ const processTimelineUpdate = (timeline: string, status: BaseStatus) =>
|
|||
return;
|
||||
}
|
||||
|
||||
dispatch(importFetchedStatus(status));
|
||||
dispatch(importEntities({ statuses: [status] }));
|
||||
|
||||
if (shouldSkipQueue) {
|
||||
dispatch(updateTimeline(timeline, status.id));
|
||||
|
@ -159,10 +159,10 @@ const handleTimelineExpand = (timelineId: string, fn: Promise<PaginatedResponse<
|
|||
dispatch(expandTimelineRequest(timelineId));
|
||||
|
||||
return fn.then(response => {
|
||||
dispatch(importFetchedStatuses(response.items));
|
||||
dispatch(importEntities({ statuses: response.items }));
|
||||
|
||||
const statuses = deduplicateStatuses(response.items);
|
||||
dispatch(importFetchedStatuses(statuses.filter(status => status.accounts)));
|
||||
dispatch(importEntities({ statuses: statuses.filter(status => status.accounts) }));
|
||||
|
||||
dispatch(expandTimelineSuccess(
|
||||
timelineId,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { importFetchedStatuses } from './importer';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
|
@ -18,7 +18,7 @@ const fetchTrendingStatuses = () =>
|
|||
dispatch({ type: TRENDING_STATUSES_FETCH_REQUEST });
|
||||
|
||||
return client.trends.getTrendingStatuses().then((statuses) => {
|
||||
dispatch(importFetchedStatuses(statuses));
|
||||
dispatch(importEntities({ statuses }));
|
||||
dispatch({ type: TRENDING_STATUSES_FETCH_SUCCESS, statuses });
|
||||
return statuses;
|
||||
}).catch(error => {
|
||||
|
|
|
@ -230,7 +230,7 @@ const Status: React.FC<IStatus> = (props) => {
|
|||
<Link key={account.acct} to={`/@${account.acct}`} className='hover:underline'>
|
||||
<bdi className='truncate'>
|
||||
<strong className='text-gray-800 dark:text-gray-200'>
|
||||
<Emojify text={status.account.display_name} emojis={status.account.emojis} />
|
||||
<Emojify text={account.display_name} emojis={account.emojis} />
|
||||
</strong>
|
||||
</bdi>
|
||||
</Link>
|
||||
|
|
|
@ -121,7 +121,7 @@ const Modal = React.forwardRef<HTMLDivElement, IModal>(({
|
|||
/>
|
||||
)}
|
||||
|
||||
<h3 className='grow truncate text-lg font-bold leading-6 text-gray-900 dark:text-white'>
|
||||
<h3 className='grow text-lg font-bold leading-6 text-gray-900 dark:text-white'>
|
||||
{title}
|
||||
</h3>
|
||||
|
||||
|
|
|
@ -154,10 +154,9 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
|||
if (!canSubmit) return;
|
||||
e?.preventDefault();
|
||||
|
||||
|
||||
dispatch(submitCompose(id, { history, onSubmit, propagate: fullScreen })).then(() => {
|
||||
dispatch(submitCompose(id, { history, onSubmit, propagate: fullScreen, onSuccess: () => {
|
||||
editorRef.current?.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined);
|
||||
}).catch(() => {});
|
||||
} }));
|
||||
};
|
||||
|
||||
const onSuggestionsClearRequested = () => {
|
||||
|
|
|
@ -8,9 +8,9 @@ import { fetchDraftStatuses } from 'pl-fe/actions/draft-statuses';
|
|||
import { fetchStatus } from 'pl-fe/actions/statuses';
|
||||
import Stack from 'pl-fe/components/ui/stack';
|
||||
import ComposeForm from 'pl-fe/features/compose/components/compose-form';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/useAppDispatch';
|
||||
import { useCompose } from 'pl-fe/hooks/useCompose';
|
||||
import { useFeatures } from 'pl-fe/hooks/useFeatures';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||
import { useCompose } from 'pl-fe/hooks/use-compose';
|
||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||
import { makeGetStatus, selectOwnAccount } from 'pl-fe/selectors';
|
||||
import { useSettingsStore } from 'pl-fe/stores/settings';
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from 'pl-fe/actions/import-data';
|
||||
import Column from 'pl-fe/components/ui/column';
|
||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||
|
||||
import DataImporter from './components/data-importer';
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import { importFetchedStatuses } from 'pl-fe/actions/importer';
|
||||
import { importEntities } from 'pl-fe/actions/importer';
|
||||
import { expandTimelineSuccess } from 'pl-fe/actions/timelines';
|
||||
import Column from 'pl-fe/components/ui/column';
|
||||
import Timeline from 'pl-fe/features/ui/components/timeline';
|
||||
|
@ -35,7 +35,7 @@ const TestTimeline: React.FC = () => {
|
|||
const isMobile = useIsMobile();
|
||||
|
||||
React.useEffect(() => {
|
||||
dispatch(importFetchedStatuses(MOCK_STATUSES));
|
||||
dispatch(importEntities({ statuses: MOCK_STATUSES }));
|
||||
dispatch(expandTimelineSuccess(timelineId, MOCK_STATUSES, null, null, false, false));
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ const MissingDescriptionModal: React.FC<BaseModalProps & MissingDescriptionModal
|
|||
confirmationText={intl.formatMessage(messages.post)}
|
||||
confirmationTheme='danger'
|
||||
cancelText={intl.formatMessage(messages.cancel)}
|
||||
cancelAction={onClose}
|
||||
cancelAction={() => onClose('MISSING_DESCRIPTION')}
|
||||
>
|
||||
<p className='text-gray-600 dark:text-gray-300'>
|
||||
<FormattedMessage id='missing_description_modal.description' defaultMessage='Continue anyway?' />
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import React from 'react';
|
||||
import { HelmetProvider } from 'react-helmet-async';
|
||||
import { Toaster } from 'react-hot-toast';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { StatProvider } from 'pl-fe/contexts/stat-context';
|
||||
|
@ -40,12 +39,6 @@ const PlFe: React.FC = () => (
|
|||
</StatProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
<div id='toaster'>
|
||||
<Toaster
|
||||
position='top-right'
|
||||
containerClassName='top-4'
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import sumBy from 'lodash/sumBy';
|
|||
import { type Chat, type ChatMessage as BaseChatMessage, type PaginatedResponse, chatMessageSchema, type Relationship } from 'pl-api';
|
||||
import * as v from 'valibot';
|
||||
|
||||
import { importFetchedAccount, importFetchedAccounts } from 'pl-fe/actions/importer';
|
||||
import { importEntities } from 'pl-fe/actions/importer';
|
||||
import { ChatWidgetScreens, useChatContext } from 'pl-fe/contexts/chat-context';
|
||||
import { useStatContext } from 'pl-fe/contexts/stat-context';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
|
@ -72,7 +72,7 @@ const useChats = () => {
|
|||
|
||||
// Set the relationships to these users in the redux store.
|
||||
fetchRelationships.mutate({ accountIds: items.map((item) => item.account.id) });
|
||||
dispatch(importFetchedAccounts(items.map((item) => item.account)));
|
||||
dispatch(importEntities({ accounts: items.map((item) => item.account) }));
|
||||
|
||||
return response;
|
||||
};
|
||||
|
@ -109,7 +109,7 @@ const useChat = (chatId?: string) => {
|
|||
const data = await client.chats.getChat(chatId);
|
||||
|
||||
fetchRelationships.mutate({ accountIds: [data.account.id] });
|
||||
dispatch(importFetchedAccount(data.account));
|
||||
dispatch(importEntities({ accounts: [data.account] }));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useMutation, keepPreviousData, useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { fetchRelationships } from 'pl-fe/actions/accounts';
|
||||
import { importFetchedAccounts } from 'pl-fe/actions/importer';
|
||||
import { importEntities } from 'pl-fe/actions/importer';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||
import { useClient } from 'pl-fe/hooks/use-client';
|
||||
|
||||
|
@ -20,7 +20,7 @@ const useSuggestions = () => {
|
|||
|
||||
const accounts = response.map(({ account }) => account);
|
||||
const accountIds = accounts.map((account) => account.id);
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importEntities({ accounts }));
|
||||
dispatch(fetchRelationships(accountIds));
|
||||
|
||||
return response.map(({ account, ...x }) => ({ ...x, account_id: account.id }));
|
||||
|
@ -60,7 +60,7 @@ const useOnboardingSuggestions = () => {
|
|||
|
||||
const accounts = response.map(({ account }) => account);
|
||||
const accountIds = accounts.map((account) => account.id);
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importEntities({ accounts }));
|
||||
dispatch(fetchRelationships(accountIds));
|
||||
|
||||
return response;
|
||||
|
|
|
@ -5,17 +5,18 @@ import * as v from 'valibot';
|
|||
import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
||||
import { usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
|
||||
const placeholderData = v.parse(instanceSchema, {});
|
||||
const initialData = v.parse(instanceSchema, {});
|
||||
|
||||
const useInstance = () => {
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
return useQuery({
|
||||
const query = useQuery({
|
||||
queryKey: ['instance'],
|
||||
queryFn: client.instance.getInstance,
|
||||
placeholderData,
|
||||
}, queryClient);
|
||||
|
||||
return { ...query, data: query.data || initialData };
|
||||
};
|
||||
|
||||
export { useInstance };
|
||||
|
|
Loading…
Reference in a new issue